home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Chans / x40088 / pptox400.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  69.4 KB  |  2,761 lines

  1. /* pptox400.c: convert PP structures to X.400 88 structures */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Chans/x40088/RCS/pptox400.c,v 6.0 1991/12/18 20:14:27 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Chans/x40088/RCS/pptox400.c,v 6.0 1991/12/18 20:14:27 jpo Rel $
  9.  *
  10.  * $Log: pptox400.c,v $
  11.  * Revision 6.0  1991/12/18  20:14:27  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "Trans-types.h"
  19. #include "Ext-types.h"
  20. #include "util.h"
  21. #include "q.h"
  22. #include "adr.h"
  23. #include "dr.h"
  24. #include "or.h"
  25. #include <isode/cmd_srch.h>
  26. #include "rtsparams.h"
  27. #include "x400_ub.h"
  28.  
  29. #define STR2QB(s)    str2qb(s, strlen(s), 1)
  30.  
  31. static int build_envelope ();
  32. static int build_msgid ();
  33. int build_addr ();
  34. static int build_addrdn ();
  35. static int build_eits ();
  36. static int build_content ();
  37. static int build_pmf ();
  38. static int build_time ();
  39. static int build_recips ();
  40. static int build_p3_recips ();
  41. static int build_ri ();
  42. static int build_p3_ri ();
  43. static int build_trace ();
  44. static int build_gdi ();
  45. static int build_pm_extensions ();
  46. static int build_prf_ext ();
  47. static int build_drenvelope ();
  48. static int build_drcontent ();
  49. static int build_drc_pr_fields ();
  50. static int build_lasttrace ();
  51. static int build_report ();
  52. static int build_fullname ();
  53. static int add_eeit ();
  54. static int setuberror ();
  55. struct type_IOB_ORName *orn2orname();
  56.  
  57. static int trace_type;
  58.  
  59. static int build_probe_envelope(), build_dehl(), build_drc_extensions(),
  60.     build_drc_pr_extensions(), build_dre_extensions();
  61.  
  62. char ub_error_string[BUFSIZ];
  63. int ub_error_set;
  64.  
  65. int build_p1 (qp, adl, p1, tt)
  66. Q_struct *qp;
  67. ADDR    *adl;
  68. struct type_Trans_MtsAPDU **p1;
  69. int tt;
  70. {
  71.     ub_error_set = NOTOK;
  72.     trace_type = tt;
  73.     *p1 = (struct type_Trans_MtsAPDU *) smalloc (sizeof **p1);
  74.     bzero ((char *)*p1, sizeof **p1);
  75.  
  76.     (*p1) -> offset = type_Trans_MtsAPDU_message;
  77.     (*p1) -> un.message = (struct type_Trans_MessageAPDU *)
  78.         smalloc (sizeof *(*p1) -> un.message);
  79.     (*p1) -> un.message -> content = NULL;
  80.     if (build_envelope (qp, adl, &(*p1) -> un.message -> envelope) == OK)
  81.         return OK;
  82.  
  83.     free_Trans_MtsAPDU (p1);
  84.     if (ub_error_set != NOTOK)
  85.         return DONE;
  86.     return NOTOK;
  87. }
  88.  
  89. int build_dr (qp, recip, dr, qb, p1dr, tt)
  90. Q_struct *qp;
  91. ADDR    *recip;
  92. DRmpdu    *dr;
  93. struct type_MTA_Content *qb;
  94. struct type_Trans_MtsAPDU **p1dr;
  95. int tt;
  96. {
  97.  
  98.     ub_error_set = NOTOK;
  99.     trace_type = tt;
  100.     *p1dr = (struct type_Trans_MtsAPDU *) smalloc (sizeof **p1dr);
  101.     bzero ((char *)*p1dr, sizeof **p1dr);
  102.  
  103.     (*p1dr) -> offset = type_Trans_MtsAPDU_report;
  104.     (*p1dr) -> un.report = (struct type_Trans_ReportAPDU *)
  105.         smalloc (sizeof *(*p1dr) -> un.report);
  106.     if (build_drenvelope (qp, dr,
  107.                   &(*p1dr) -> un.report -> envelope) == OK &&
  108.         build_drcontent (qp, recip, dr, qb,
  109.                  &(*p1dr) -> un.report -> content) == OK)
  110.         return OK;
  111.     free_Trans_MtsAPDU (p1dr);
  112.     if (ub_error_set != NOTOK)
  113.         return DONE;
  114.     return NULL;
  115. }
  116.  
  117.  
  118. int build_probe (qp, recip, p1, tt)
  119. Q_struct *qp;
  120. ADDR    *recip;
  121. struct type_Trans_MtsAPDU **p1;
  122. int tt;
  123. {
  124.     ub_error_set = NOTOK;
  125.     trace_type = tt;
  126.     *p1 = (struct type_Trans_MtsAPDU *) smalloc (sizeof **p1);
  127.     bzero ((char *)*p1, sizeof **p1);
  128.  
  129.     (*p1) -> offset = type_Trans_MtsAPDU_probe;
  130.     if (build_probe_envelope (qp, recip, &(*p1) -> un.probe) == OK)
  131.         return OK;
  132.  
  133.     free_Trans_MtsAPDU (*p1);
  134.     if (ub_error_set != NOTOK)
  135.         return DONE;
  136.     return NOTOK;
  137. }
  138.  
  139. static int build_envelope (qp, adl, envp)
  140. Q_struct *qp;
  141. ADDR    *adl;
  142. struct type_MTA_MessageTransferEnvelope **envp;
  143. {
  144.     struct type_MTA_MessageTransferEnvelope *env;
  145.  
  146.     *envp = env = (struct type_MTA_MessageTransferEnvelope *)
  147.         smalloc (sizeof *env);
  148.     bzero ((char *)env, sizeof *env);
  149.  
  150.     if (build_msgid (&qp->msgid, &env -> message__identifier) == NOTOK)
  151.         return NOTOK;
  152.  
  153.     if (build_addrdn (qp -> Oaddress -> ad_r400adr,
  154.             qp -> Oaddress -> ad_dn,
  155.             &env -> originator__name) == NOTOK)
  156.         return NOTOK;
  157.  
  158.  
  159.     if (build_eits (&qp -> encodedinfo,
  160.             &env -> original__encoded__information__types) == NOTOK)
  161.         return NOTOK;
  162.  
  163.     if (build_content (adl -> ad_content ?
  164.                adl -> ad_content :
  165.                qp -> cont_type,
  166.                &env -> member_MTA_13) == NOTOK)
  167.         return NOTOK;
  168.  
  169.  
  170.     if (qp -> ua_id) {
  171.         if ((int) strlen(qp -> ua_id) > UB_CONTENT_ID_LENGTH)
  172.             return setuberror ("Content Id", strlen(qp -> ua_id),
  173.                        UB_CONTENT_ID_LENGTH,
  174.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  175.         if ((env -> content__identifier =
  176.              STR2QB (qp -> ua_id)) == NULL)
  177.             return NOTOK;
  178.     }
  179.  
  180.     env -> priority = (struct type_MTA_Priority *)
  181.         smalloc (sizeof *env -> priority);
  182.     env -> priority -> parm = qp -> priority;
  183.  
  184.     if (build_pmf (qp,
  185.                &env -> per__message__indicators) == NOTOK)
  186.         return NOTOK;
  187.  
  188.     if (qp -> defertime &&
  189.         build_time (qp -> defertime,
  190.             &env -> deferred__delivery__time) == NOTOK)
  191.         return NOTOK;
  192.  
  193.     env -> per__domain__bilateral__information = NULL;
  194.  
  195.     if (build_pm_extensions (qp,1,1,
  196.                  &env -> extensions) == NOTOK)
  197.         return NOTOK;
  198.  
  199.     if (build_trace (qp->trace,
  200.              &env -> trace__information) == NOTOK)
  201.         return NOTOK;
  202.  
  203.     if (build_recips (qp -> disclose_recips ?
  204.               qp -> Raddress : adl, adl,
  205.               qp->disclose_recips,
  206.               &env -> per__recipient__fields) == NOTOK)
  207.               return NOTOK;
  208.  
  209.     return OK;
  210. }
  211.  
  212.  
  213.  
  214.  
  215. int build_p3_envelope (qp, envp, tt)
  216. Q_struct *qp;
  217. struct type_MTA_MessageSubmissionEnvelope **envp;
  218. int    tt;
  219. {
  220.     struct type_MTA_MessageSubmissionEnvelope *env;
  221.  
  222.     trace_type = tt;
  223.     *envp = env = (struct type_MTA_MessageSubmissionEnvelope *)
  224.         smalloc (sizeof *env);
  225.     bzero ((char *)env, sizeof *env);
  226.  
  227.  
  228.     if (build_addrdn (qp -> Oaddress -> ad_r400adr,
  229.             qp -> Oaddress -> ad_dn,
  230.             &env -> originator__name) == NOTOK)
  231.         return NOTOK;
  232.  
  233.  
  234.     if (build_eits (&qp -> orig_encodedinfo,
  235.             &env -> original__eits) == NOTOK)
  236.         return NOTOK;
  237.  
  238.     if (build_content (qp -> cont_type,
  239.                &env -> member_MTA_6) == NOTOK)
  240.         return NOTOK;
  241.  
  242.     if (qp -> ua_id) {
  243.         if ((int) strlen(qp -> ua_id) > UB_CONTENT_ID_LENGTH)
  244.             return setuberror ("Content Id", strlen(qp -> ua_id),
  245.                        UB_CONTENT_ID_LENGTH,
  246.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  247.         if ((env -> content__identifier =
  248.              STR2QB (qp -> ua_id)) == NULL)
  249.             return NOTOK;
  250.     }
  251.     env -> priority = (struct type_MTA_Priority *)
  252.         smalloc (sizeof *env -> priority);
  253.  
  254.     env -> priority -> parm =
  255.         qp -> priority ? qp -> priority : PRIO_NORMAL;
  256.  
  257.     if (build_pmf (qp,
  258.                &env -> per__message__indicators) == NOTOK)
  259.         return NOTOK;
  260.  
  261.     if (qp -> defertime &&
  262.         build_time (qp -> defertime,
  263.             &env -> deferred__delivery__time) == NOTOK)
  264.         return NOTOK;
  265.  
  266.     if (build_pm_extensions (qp,0,1,
  267.                  &env -> extensions) == NOTOK)
  268.         return NOTOK;
  269.  
  270.     if (build_p3_recips (qp -> Raddress,
  271.                  &env -> per__recipient__fields) == NOTOK)
  272.         return NOTOK;
  273.  
  274.     return OK;
  275. }
  276.  
  277.  
  278. static int build_msgid (mid, p1mp)
  279. MPDUid *mid;
  280. struct type_MTA_MTSIdentifier **p1mp;
  281. {
  282.     struct type_MTA_MTSIdentifier *p1msgid;
  283.  
  284.     *p1mp = p1msgid = (struct type_MTA_MTSIdentifier *)
  285.         smalloc (sizeof *p1msgid);
  286.     bzero ((char *)p1msgid, sizeof *p1msgid);
  287.  
  288.     if (mid -> mpduid_string) {
  289.         if ((int) strlen(mid -> mpduid_string) > UB_LOCAL_ID_LENGTH)
  290.             return setuberror ("LocalId",
  291.                        strlen(mid -> mpduid_string),
  292.                        UB_LOCAL_ID_LENGTH,
  293.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  294.         if ((p1msgid -> local__identifier =
  295.              STR2QB (mid -> mpduid_string)) == NULL)
  296.             return NOTOK;
  297.     }
  298.     if (build_gdi (&mid -> mpduid_DomId,
  299.                &p1msgid -> global__domain__identifier) == NOTOK)
  300.         return NOTOK;
  301.     return OK;
  302. }
  303.  
  304. static int build_addrdn (cp, dn, ornp)
  305. char    *cp;
  306. char *dn;
  307. struct type_MTA_ORName **ornp;
  308. {
  309.     OR_ptr or;
  310.     ORName *orn;
  311.     struct type_IOB_ORName *orname;
  312.  
  313.     orn = (ORName *) calloc (1, sizeof *orn);
  314.     if ((or = or_std2or (cp)) == NULLOR) {
  315.         PP_LOG (LLOG_EXCEPTIONS, ("Can't convert %s", cp));
  316.         ORName_free (orn);
  317.         return NOTOK;
  318.     }
  319.     orn -> on_or = or;
  320.     if (dn)
  321.         orn -> on_dn = str2dn (dn);
  322.     orname = orn2orname (orn);
  323.     ORName_free (orn);
  324.     *ornp = (struct type_MTA_ORName *)orname;
  325.     return  OK;
  326. }
  327.  
  328. int build_addr (cp, orap)
  329. char    *cp;
  330. struct type_MTA_ORAddress **orap;
  331. {
  332.     OR_ptr or;
  333.     extern struct type_MTA_ORAddress *ora2oradr();
  334.  
  335.     if ((or = or_std2or (cp)) == NULLOR) {
  336.         PP_LOG (LLOG_EXCEPTIONS, ("Can't convert %s", cp));
  337.         or_free (or);
  338.         return NOTOK;
  339.     }
  340.     *orap = ora2oradr (or);
  341.     or_free (or);
  342.     return  OK;
  343. }
  344.  
  345.  
  346. static int build_eits (eit, p1eitp)
  347. EncodedIT *eit;
  348. struct type_MTA_EncodedInformationTypes **p1eitp;
  349. {
  350.     struct type_MTA_EncodedInformationTypes *p1eit;
  351.     LIST_BPT                *ep;
  352.     int                    n;
  353.     PE                    pe;
  354.  
  355.  
  356.     if (eit == NULL) return NULL;
  357.  
  358.     if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_BITS))
  359.         == NULLPE)
  360.         return NOTOK;
  361.  
  362.     *p1eitp = p1eit = (struct type_MTA_EncodedInformationTypes *)
  363.         smalloc (sizeof *p1eit);
  364.     bzero ((char *)p1eit, sizeof *p1eit);
  365.     p1eit -> built__in__encoded__information__types = NULL;
  366.     p1eit -> external__encoded__information__types = NULL;
  367.  
  368.  
  369.     for (ep = eit -> eit_types; ep; ep = ep -> li_next) {
  370.         switch (n = bodypart2value (ep -> li_name)) {
  371.         case NOTOK:
  372.             /* -- unrecognised -- */
  373.             break;
  374.         case 10:
  375.             /* -- object id -- */
  376.             if (add_eeit (&p1eit->external__encoded__information__types,
  377.                       (ep -> li_name + strlen("oid."))) == NOTOK)
  378.                 return NOTOK;
  379.             break;
  380.         default:
  381.             if (n > UB_BUILT_IN_ENCODED_INFORMATION_TYPES)
  382.                 return setuberror ("BuiltInEit",
  383.                            n, UB_BUILT_IN_ENCODED_INFORMATION_TYPES,
  384.                            DRD_SIZE_CONSTRAINT_VIOLATION);
  385.             /* -- recognised eit -- */
  386.             if (bit_on(pe,n) == NOTOK)
  387.                 return NOTOK;
  388.             break;    
  389.         }
  390.     }
  391.  
  392.     p1eit -> built__in__encoded__information__types = pe;
  393.  
  394.     return OK;
  395. }
  396.  
  397.  
  398.  
  399. static int add_eeit (eep, oidn)
  400. struct type_MTA_ExternalEncodedInformationTypes **eep;
  401. char    *oidn;
  402. {
  403.     int n;
  404.     if (*eep == NULL) {
  405.         *eep = (struct type_MTA_ExternalEncodedInformationTypes *)
  406.             calloc (1, sizeof **eep);
  407.         (*eep) -> ExternalEncodedInformationType = str2oid (oidn);
  408.     }
  409.     else {
  410.         struct type_MTA_ExternalEncodedInformationTypes *ep;
  411.  
  412.         for (n = 0, ep = *eep; ep -> next; ep = ep -> next, n++)
  413.             continue;
  414.         if (n > UB_ENCODED_INFORMATION_TYPES)
  415.             return setuberror ("EncodedInfoTypes",
  416.                        n, UB_ENCODED_INFORMATION_TYPES,
  417.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  418.         ep -> next = (struct type_MTA_ExternalEncodedInformationTypes *)
  419.             calloc (1, sizeof *ep);
  420.         ep -> next -> ExternalEncodedInformationType =
  421.             str2oid (oidn);
  422.     }
  423.     return OK;
  424. }
  425.  
  426. static int build_content (str, bictp)
  427. char    *str;
  428. struct type_MTA_ContentType **bictp;
  429. {
  430.     struct type_MTA_ContentType *bict;
  431.  
  432.     *bictp = bict = (struct type_MTA_ContentType *)
  433.         smalloc (sizeof *bict);
  434.  
  435.     bzero ((char *)bict, sizeof *bict);
  436.     if (lexnequ (str, "oid.", 4) == 0) {
  437.         bict -> offset = type_MTA_ContentType_external;
  438.         bict -> un.external = str2oid(str+4);
  439.         return OK;
  440.     }
  441.     bict -> offset = type_MTA_ContentType_built__in;
  442.     bict -> un.built__in = (struct type_MTA_BuiltInContentType *)
  443.         smalloc (sizeof *bict->un.built__in);
  444.     if (lexequ (str, "p2") == 0)
  445.         bict -> un.built__in -> parm =
  446.             int_MTA_BuiltInContentType_interpersonal__messaging__1984;
  447.     else if (lexequ (str, "p22") == 0)
  448.         bict -> un.built__in -> parm =
  449.             int_MTA_BuiltInContentType_interpersonal__messaging__1988;
  450.     else if (lexequ (str, "external") == 0)
  451.         bict -> un.built__in -> parm =
  452.             int_MTA_BuiltInContentType_external;
  453.     else
  454.         bict -> un.built__in -> parm =
  455.             int_MTA_BuiltInContentType_unidentified;
  456.  
  457.     return OK;
  458. }
  459.  
  460. static int build_pmf (qp, pep)
  461. Q_struct *qp;
  462. PE    *pep;
  463. {
  464.     PE pe;
  465.  
  466.     if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_BITS))
  467.         == NULLPE)
  468.         return NOTOK;
  469.     *pep = pe;
  470.  
  471.     if (qp -> disclose_recips &&
  472.         bit_on(pe, bit_MTA_PerMessageIndicators_disclosure__of__recipients)
  473.         == NOTOK)
  474.         return NOTOK;
  475.     if (qp -> implicit_conversion_prohibited &&
  476.         bit_on(pe, bit_MTA_PerMessageIndicators_implicit__conversion__prohibited)
  477.         == NOTOK)
  478.         return NOTOK;
  479.     if (qp -> alternate_recip_allowed &&
  480.         bit_on(pe, bit_MTA_PerMessageIndicators_alternate__recipient__allowed)
  481.         == NOTOK)
  482.         return NOTOK;
  483.     if (qp -> content_return_request &&
  484.         bit_on(pe, bit_MTA_PerMessageIndicators_content__return__request)
  485.         == NOTOK)
  486.         return NOTOK;
  487.  
  488.     return OK;
  489. }
  490.  
  491. static int build_time (utc, utp)
  492. UTC    utc;
  493. struct type_UNIV_UTCTime **utp;
  494. {
  495.     char    *str;
  496.  
  497.     str = utct2str (utc);
  498.     
  499.     if((*utp = STR2QB (str)) == NULL)
  500.         return NOTOK;
  501.     return OK;
  502. }
  503.  
  504. static int build_recips (ad, adl, disclose, rlp)
  505. ADDR    *ad;
  506. ADDR    *adl;
  507. int    disclose;
  508. struct element_MTA_4 **rlp;
  509. {
  510.     struct element_MTA_4 *rl = NULL;
  511.     struct type_MTA_PerRecipientMessageTransferFields *prmtf;
  512.     ADDR    *ap, *ap2;
  513.     int    resp;
  514.     int     naddr = 0;
  515.  
  516.     *rlp = NULL;
  517.     for (ap = ad; ap; ap = ap -> ad_next) {
  518.         for (ap2 = adl; ap2; ap2 = ap2 -> ad_next) {
  519.             if (ap2 -> ad_no == ap -> ad_no)
  520.                 break;
  521.         }
  522.         if (ap2 == NULLADDR)
  523.             resp = FALSE;
  524.         else    
  525.             resp = ap2 -> ad_resp;
  526.                 
  527.  
  528.         if (*rlp == NULL) 
  529.             *rlp = rl = (struct element_MTA_4 *)
  530.                 smalloc (sizeof *rl);
  531.         else {
  532.             rl -> next = (struct element_MTA_4 *)
  533.                 smalloc (sizeof *rl);
  534.             rl = rl -> next;
  535.         }
  536.         bzero ((char *)rl, sizeof *rl);
  537.         prmtf = rl -> PerRecipientMessageTransferFields =
  538.             (struct type_MTA_PerRecipientMessageTransferFields *)
  539.             smalloc (sizeof *prmtf);
  540.         bzero ((char *)prmtf, sizeof *prmtf);
  541.  
  542.         if (build_addrdn (ap -> ad_r400adr,
  543.                 ap -> ad_dn,
  544.                 &prmtf -> recipient__name) == NOTOK)
  545.             return NOTOK;
  546.  
  547.         prmtf -> originally__specified__recipient__number =
  548.             (struct type_MTA_OriginallySpecifiedRecipientNumber *)
  549.             smalloc (sizeof *prmtf ->
  550.                  originally__specified__recipient__number);
  551.         prmtf -> originally__specified__recipient__number -> parm =
  552.             ap -> ad_extension;
  553.  
  554.         if (ap -> ad_explicitconversion != AD_EXP_NONE) {
  555.             if (ap -> ad_explicitconversion > UB_INTEGER_OPTIONS)
  556.                 return setuberror("ExplicitConversion", 
  557.                           ap -> ad_explicitconversion,
  558.                           UB_INTEGER_OPTIONS,
  559.                           DRD_SIZE_CONSTRAINT_VIOLATION);
  560.             prmtf -> explicit__conversion =
  561.  
  562.                 (struct type_MTA_ExplicitConversion *)
  563.                     smalloc (sizeof *prmtf -> explicit__conversion);
  564.             prmtf -> explicit__conversion -> parm =
  565.                 ap -> ad_explicitconversion;
  566.         }
  567.         else prmtf -> explicit__conversion = NULL;
  568.  
  569.         if (build_ri (resp,
  570.                   ap -> ad_mtarreq,
  571.                   ap -> ad_usrreq,
  572.                   &prmtf -> per__recipient__indicators) == NOTOK)
  573.             return NOTOK;
  574.  
  575.         if (build_prf_ext (ap,1,1,
  576.                    &prmtf -> extensions) == NOTOK)
  577.             return NOTOK;
  578.         if (naddr++ > UB_RECIPIENTS)
  579.             return setuberror("Max number of recipients", naddr,
  580.                       UB_RECIPIENTS, DRD_TOO_MANY_RECIPIENTS);
  581.     }
  582.     return OK;
  583. }
  584.  
  585.  
  586. static int build_p3_recips (ad, rlp)
  587. ADDR    *ad;
  588. struct element_MTA_0 **rlp;
  589. {
  590.     struct element_MTA_0 *rl = NULL;
  591.     struct type_MTA_PerRecipientMessageSubmissionFields *prmtf;
  592.     ADDR    *ap;
  593.     int naddr = 0;
  594.  
  595.     *rlp = NULL;
  596.     for (ap = ad; ap; ap = ap -> ad_next) {
  597.  
  598.         if (*rlp == NULL) 
  599.             *rlp = rl = (struct element_MTA_0 *)
  600.                 smalloc (sizeof *rl);
  601.         else {
  602.             rl -> next = (struct element_MTA_0 *)
  603.                 smalloc (sizeof *rl);
  604.             rl = rl -> next;
  605.         }
  606.         bzero ((char *)rl, sizeof *rl);
  607.         prmtf = rl -> PerRecipientMessageSubmissionFields =
  608.             (struct type_MTA_PerRecipientMessageSubmissionFields *)
  609.             smalloc (sizeof *prmtf);
  610.         if (build_addrdn (ap -> ad_r400adr, ap -> ad_dn,
  611.                 &prmtf -> recipient__name) == NOTOK)
  612.             return NOTOK;
  613.  
  614.         if (ap -> ad_explicitconversion != AD_EXP_NONE) {
  615.             prmtf -> explicit__conversion =
  616.                 (struct type_MTA_ExplicitConversion *)
  617.                     smalloc (sizeof *prmtf -> explicit__conversion);
  618.             prmtf -> explicit__conversion -> parm =
  619.                 ap -> ad_explicitconversion;
  620.         }
  621.         else prmtf -> explicit__conversion = NULL;
  622.  
  623.         if (build_p3_ri (ap -> ad_usrreq,
  624.                  &prmtf     -> originator__report__request)
  625.             == NOTOK)
  626.             return NOTOK;
  627.         if (build_prf_ext (ap,0,1,
  628.                    &prmtf -> extensions) == NOTOK)
  629.             return NOTOK;
  630.         if (naddr++ > UB_RECIPIENTS)
  631.             return setuberror("Max number of recipients", naddr,
  632.                       UB_RECIPIENTS,
  633.                       DRD_TOO_MANY_RECIPIENTS);
  634.     }
  635.     return OK;
  636. }
  637.  
  638. static int build_ri (resp, mta, usr, pep)
  639. int    resp, mta, usr;
  640. PE    *pep;
  641. {
  642.     PE    pe;
  643.  
  644.     if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_BITS))
  645.         == NULLPE)
  646.         return NOTOK;
  647.     *pep = pe;
  648.     if (resp && bit_on(pe,
  649.                bit_MTA_PerRecipientIndicators_responsibility) == NOTOK)
  650.         return NOTOK;
  651.  
  652.     switch (mta) {
  653.         case AD_MTA_NONE:
  654.         break;
  655.         case AD_MTA_BASIC:
  656.         if (bit_on(pe,
  657.                bit_MTA_PerRecipientIndicators_originating__MTA__non__delivery__report) == NOTOK)
  658.             return NOTOK;
  659.         break;
  660.         case AD_MTA_CONFIRM:
  661.         if (bit_on(pe,
  662.             bit_MTA_PerRecipientIndicators_originating__MTA__report) == NOTOK)
  663.             return NOTOK;
  664.         break;
  665.         case AD_MTA_AUDIT_CONFIRM:
  666.         if (bit_on(pe,
  667.                bit_MTA_PerRecipientIndicators_originating__MTA__non__delivery__report) == NOTOK ||
  668.             bit_on(pe,
  669.                bit_MTA_PerRecipientIndicators_originating__MTA__report) == NOTOK)
  670.             return NOTOK;
  671.         break;
  672.     }
  673.  
  674.     switch (usr) {
  675.         case AD_USR_NOREPORT:
  676.         break;
  677.         case AD_USR_BASIC:
  678.         if (bit_on(pe,
  679.                bit_MTA_PerRecipientIndicators_originator__non__delivery__report) == NOTOK)
  680.             return NOTOK;
  681.         break;
  682.         case AD_USR_CONFIRM:
  683.         if (bit_on(pe,
  684.             bit_MTA_PerRecipientIndicators_originator__report) == NOTOK)
  685.             return NOTOK;
  686.         break;
  687.     }
  688.     if (bit_test (pe, 8) == NOTOK)
  689.         (void) bit_off (pe, 8);
  690.     return OK;
  691. }
  692.  
  693.  
  694. static int build_p3_ri (usr, pep)
  695. int     usr;
  696. PE    *pep;
  697. {
  698.     PE      pe;
  699.  
  700.     if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_BITS))
  701.         == NULLPE)
  702.         return NOTOK;
  703.     *pep = pe;
  704.  
  705.     switch (usr) {
  706.         case AD_USR_NOREPORT:
  707.         case AD_USR_BASIC:
  708.             if (bit_on(pe,
  709.                    bit_MTA_OriginatorReportRequest_non__delivery__report) == NOTOK)
  710.                 return NOTOK;
  711.             break;
  712.         case AD_USR_CONFIRM:
  713.             if (bit_on(pe,bit_MTA_OriginatorReportRequest_report)
  714.                 == NOTOK)
  715.                 return NOTOK;
  716.             break;
  717.     }
  718.     return OK;
  719. }
  720.  
  721. static int build_traceelement (tp, tiep)
  722. Trace    *tp;
  723. struct type_MTA_TraceInformationElement **tiep;
  724. {
  725.     struct type_MTA_TraceInformationElement *tie;
  726.     struct type_MTA_DomainSuppliedInformation *dsi;
  727.     DomSupInfo *dsp;
  728.  
  729.     *tiep = tie = (struct type_MTA_TraceInformationElement *)
  730.         smalloc (sizeof *tie);
  731.     bzero ((char *)tie, sizeof *tie);
  732.  
  733.     if (build_gdi (&tp -> trace_DomId,
  734.                &tie -> global__domain__identifier) == NOTOK)
  735.         return NOTOK;
  736.  
  737.     dsp = &tp -> trace_DomSinfo;
  738.     dsi = tie -> domain__supplied__information =
  739.         (struct type_MTA_DomainSuppliedInformation *)
  740.             smalloc (sizeof *tie ->
  741.                  domain__supplied__information);
  742.     bzero ((char *)dsi, sizeof *dsi);
  743.     if (dsp -> dsi_time &&
  744.         build_time (dsp -> dsi_time,
  745.             &dsi -> arrival__time) == NOTOK)
  746.         return NOTOK;
  747.  
  748.     dsi -> routing__action =
  749.         (struct type_MTA_RoutingAction *)
  750.             smalloc (sizeof *dsi -> routing__action);
  751.     if (dsp -> dsi_action)
  752.         dsi -> routing__action -> parm = dsp -> dsi_action;
  753.     else    dsi -> routing__action -> parm = 
  754.         int_MTA_RoutingAction_relayed;
  755.  
  756.     if (dsp -> dsi_attempted_md.global_Country != NULLCP &&
  757.         dsp -> dsi_attempted_md.global_Admin != NULLCP)
  758.         if (build_gdi (&dsp -> dsi_attempted_md,
  759.                    &dsi -> attempted__domain) == NOTOK)
  760.             return NOTOK;
  761.  
  762.     if (dsp -> dsi_deferred &&
  763.         build_time (dsp -> dsi_deferred,
  764.             &dsi -> deferred__time) == NOTOK)
  765.         return NOTOK;
  766.  
  767.     if (dsp -> dsi_converted.eit_types &&
  768.         build_eits (&dsp -> dsi_converted,
  769.             &dsi -> converted__encoded__information__types) == NOTOK)
  770.         return NOTOK;
  771.  
  772.     if (dsp -> dsi_other_actions) {
  773.         if ((dsi -> other__actions =
  774.              pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM,
  775.                    PE_PRIM_BITS)) == NULLPE)
  776.             return NOTOK;
  777.         if (dsp -> dsi_other_actions & ACTION_REDIRECTED &&
  778.             bit_on(dsi -> other__actions,
  779.                bit_MTA_OtherActions_redirected) == NOTOK)
  780.             return NOTOK;
  781.         if (dsp -> dsi_other_actions & ACTION_EXPANDED &&
  782.             bit_on(dsi -> other__actions,
  783.                bit_MTA_OtherActions_dl__operation) == NOTOK)
  784.             return NOTOK;
  785.     }
  786.     return OK;
  787. }
  788.  
  789. int same_prmd (tp1, tp2)
  790. Trace    *tp1, *tp2;
  791. {
  792.     GlobalDomId *d1, *d2;
  793.  
  794.     d1 = &tp1 -> trace_DomId;
  795.     d2 = &tp2 -> trace_DomId;
  796.  
  797.     if (d1 -> global_Country && d2 -> global_Country &&
  798.         lexequ (d1 -> global_Country, d2 -> global_Country) == 0 &&
  799.         d1 -> global_Admin && d2 -> global_Admin &&
  800.         lexequ (d1 -> global_Admin, d2 -> global_Admin) == 0) {
  801.         if (d1 -> global_Private == NULL &&
  802.             d2 -> global_Private == NULL)
  803.             return 1;
  804.         if (d1 -> global_Private && d2 -> global_Private &&
  805.             lexequ (d1 -> global_Private, d2 -> global_Private) == 0)
  806.             return 1;
  807.     }
  808.     return 0;
  809.         
  810. }
  811.  
  812. static int build_trace (trp, tracep)
  813. Trace    *trp;
  814. struct type_MTA_TraceInformation **tracep;
  815. {
  816.     Trace    *tp, *tlast;
  817.     struct type_MTA_TraceInformation *trace = NULL;
  818.     int    ntrace = 0;
  819.  
  820.     *tracep = NULL;
  821.  
  822.     for (tlast = trp; tlast && tlast -> trace_next;
  823.          tlast = tlast -> trace_next)
  824.         continue;
  825.  
  826.     if (trace_type == RTSP_TRACE_ADMD) {
  827.         if (tlast != trp && same_prmd (tlast, trp))
  828.             tp = trp;
  829.         else    tp = tlast;
  830.         *tracep = trace = (struct type_MTA_TraceInformation *)
  831.             smalloc (sizeof *trace);
  832.         trace -> next = NULL;
  833.  
  834.         if (build_traceelement (tp,
  835.                     &trace -> TraceInformationElement)
  836.             == NOTOK)
  837.             return NOTOK;
  838.         return OK;
  839.     }
  840.             
  841.     for (tp = trp; tp; tp = tp -> trace_next) {
  842.         if (*tracep == NULL)
  843.             *tracep = trace =
  844.                 (struct type_MTA_TraceInformation *)
  845.                     smalloc (sizeof *trace);
  846.         else {
  847.             trace -> next =
  848.                 (struct type_MTA_TraceInformation *)
  849.                     smalloc (sizeof *trace);
  850.             trace = trace -> next;
  851.         }
  852.         bzero ((char *)trace, sizeof *trace);
  853.  
  854.         if (build_traceelement(tp,
  855.                        &trace -> TraceInformationElement)
  856.             == NOTOK)
  857.             return NOTOK;
  858.         if (++ntrace > UB_TRANSFERS)
  859.             return setuberror ("Trace",
  860.                        ntrace, UB_TRANSFERS,
  861.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  862.     }
  863.  
  864.     return OK;
  865. }
  866.  
  867. static int build_gdi (gdi, p1gdip)
  868. GlobalDomId *gdi;
  869. struct type_MTA_GlobalDomainIdentifier **p1gdip;
  870. {
  871.     struct type_MTA_GlobalDomainIdentifier *p1gdi;
  872.     struct type_MTA_AdministrationDomainName *admd;
  873.     struct type_MTA_CountryName *co;
  874.     struct type_MTA_PrivateDomainIdentifier *prmd;
  875.  
  876.     *p1gdip = p1gdi = (struct type_MTA_GlobalDomainIdentifier *)
  877.         smalloc (sizeof *p1gdi);
  878.     bzero ((char *)p1gdi, sizeof *p1gdi);
  879.     
  880.     if (gdi -> global_Country) {
  881.         p1gdi -> country__name = co =
  882.             (struct type_MTA_CountryName *)
  883.                 smalloc (sizeof *co);
  884.         if (or_str_isns(gdi -> global_Country)) {
  885.             if ((int) strlen(gdi -> global_Country) >
  886.                 UB_COUNTRY_NAME_NUMERIC_LENGTH)
  887.                 return setuberror ("NumericCountryLength",
  888.                            strlen(gdi -> global_Country),
  889.                            UB_COUNTRY_NAME_NUMERIC_LENGTH,
  890.                            DRD_SIZE_CONSTRAINT_VIOLATION);
  891.             co -> offset = type_MTA_CountryName_x121__dcc__code;
  892.             if ((co -> un.x121__dcc__code =
  893.                  STR2QB (gdi -> global_Country)) == NULL)
  894.                 return NOTOK;
  895.         } else {
  896.             if ((int) strlen(gdi -> global_Country) >
  897.                 UB_COUNTRY_NAME_ALPHA_LENGTH)
  898.                 return setuberror ("Country",
  899.                            strlen(gdi -> global_Country),
  900.                            UB_COUNTRY_NAME_ALPHA_LENGTH,
  901.                            DRD_SIZE_CONSTRAINT_VIOLATION);
  902.             co -> offset = type_MTA_CountryName_iso__3166__alpha2__code;
  903.             if ((co -> un.iso__3166__alpha2__code =
  904.                  STR2QB (gdi -> global_Country)) == NULL)
  905.                 return NOTOK;
  906.         }
  907.     }
  908.     else {
  909.         PP_LOG (LLOG_EXCEPTIONS, ("Country missing from GDI"));
  910.         return NOTOK;
  911.     }
  912.  
  913.     if (gdi -> global_Admin) {
  914.         if ((int) strlen(gdi -> global_Admin) > UB_DOMAIN_NAME_LENGTH)
  915.             return setuberror ("ADMD", strlen(gdi -> global_Admin),
  916.                        UB_DOMAIN_NAME_LENGTH,
  917.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  918.         p1gdi -> administration__domain__name = admd =
  919.             (struct type_MTA_AdministrationDomainName *)
  920.                 smalloc (sizeof *admd);
  921.  
  922.         if (or_str_isns (gdi -> global_Admin)) {
  923.             admd -> offset = type_MTA_AdministrationDomainName_numeric;
  924.             if ((admd -> un.numeric =
  925.                  STR2QB(gdi -> global_Admin)) == NULL)
  926.                 return NOTOK;
  927.         } else {
  928.             admd -> offset = type_MTA_AdministrationDomainName_printable;
  929.             if ((admd -> un.printable = STR2QB (gdi -> global_Admin))
  930.                 == NULL)
  931.                 return NOTOK;
  932.         }
  933.     }
  934.     else {
  935.         PP_LOG (LLOG_EXCEPTIONS, ("ADMD missing from GDI"));
  936.         return NOTOK;
  937.     }
  938.  
  939.     if (gdi -> global_Private) {
  940.         if ((int) strlen(gdi -> global_Private) > UB_DOMAIN_NAME_LENGTH)
  941.             return setuberror ("PrivateDomainIdentifier",
  942.                        strlen(gdi -> global_Private),
  943.                        UB_DOMAIN_NAME_LENGTH,
  944.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  945.         p1gdi -> private__domain__identifier = prmd =
  946.             (struct type_MTA_PrivateDomainIdentifier *)
  947.                 smalloc (sizeof *prmd);
  948.         if (or_str_isns (gdi -> global_Private)) {
  949.             prmd -> offset = type_MTA_PrivateDomainIdentifier_numeric;
  950.             if ((prmd -> un.numeric = STR2QB (gdi -> global_Private))
  951.                 == NULL)
  952.                 return NOTOK;
  953.         } else {
  954.             prmd -> offset = type_MTA_PrivateDomainIdentifier_printable;
  955.             if ((prmd -> un.printable = STR2QB (gdi -> global_Private))
  956.                 == NULL)
  957.                 return NOTOK;
  958.         }
  959.     }
  960.  
  961.     return OK;
  962. }
  963.  
  964.  
  965. static int build_drenvelope (qp, dr, envp)
  966. Q_struct *qp;
  967. DRmpdu    *dr;
  968. struct type_MTA_ReportTransferEnvelope **envp;
  969. {
  970.     struct type_MTA_ReportTransferEnvelope *env;
  971.  
  972.     *envp = env = (struct type_MTA_ReportTransferEnvelope *)
  973.         smalloc (sizeof *env);
  974.     bzero ((char *)env, sizeof *env);
  975.  
  976.  
  977.     if (build_msgid (dr -> dr_mpduid, &env -> report__identifier) == NOTOK)
  978.         return NOTOK;
  979.  
  980.     if (build_addrdn (qp -> Oaddress -> ad_r400adr,
  981.             qp -> Oaddress -> ad_dn,
  982.             &env -> report__destination__name) == NOTOK)
  983.         return NOTOK;
  984.  
  985.     if (build_trace (dr -> dr_trace,
  986.              &env -> trace__information) == NOTOK)
  987.         return NOTOK;
  988.  
  989.     if (build_dre_extensions (dr, &env -> extensions) == NOTOK)
  990.         return NOTOK;
  991.  
  992.     return OK;
  993. }
  994.  
  995. static int build_drcontent (qp, recip, dr, qb, drcp)
  996. Q_struct *qp;
  997. ADDR    *recip;
  998. DRmpdu    *dr;
  999. struct type_MTA_Content *qb;
  1000. struct type_MTA_ReportTransferContent **drcp;
  1001. {
  1002.     struct type_MTA_ReportTransferContent *drc;
  1003.  
  1004.     *drcp = drc = (struct type_MTA_ReportTransferContent *)
  1005.         smalloc (sizeof *drc);
  1006.  
  1007.     bzero ((char *)drc, sizeof *drc);
  1008.  
  1009.  
  1010.     if (build_msgid (&qp -> msgid, &drc -> subject__identifier) == NOTOK)
  1011.         return NOTOK;
  1012.  
  1013.  
  1014.     if (build_trace (dr -> dr_subject_intermediate_trace,
  1015.              &drc -> subject__intermediate__trace__information) == NOTOK)
  1016.         return NOTOK;
  1017.  
  1018.     if (build_eits (&qp -> encodedinfo,
  1019.             &drc -> original__encoded__information__types) == NOTOK)
  1020.         return NOTOK;
  1021.  
  1022.     if ((qp -> cont_type || recip -> ad_content) &&
  1023.         build_content (qp -> cont_type,
  1024.                &drc -> member_MTA_17) == NOTOK)
  1025.         return NOTOK;
  1026.  
  1027.     if (qp -> ua_id) {
  1028.         if ((int) strlen(qp -> ua_id) > UB_CONTENT_ID_LENGTH)
  1029.             return setuberror ("Content ID", qp -> msgsize,
  1030.                        UB_CONTENT_ID_LENGTH,
  1031.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  1032.         if ((drc -> content__identifier =
  1033.              STR2QB (qp -> ua_id)) == NULL)
  1034.         return NOTOK;
  1035.     }
  1036.     drc -> returned__content = qb;
  1037.  
  1038.     drc -> additional__information = NULLPE;
  1039.  
  1040.     if (build_drc_extensions (qp, recip, dr,
  1041.                &drc -> extensions) == NOTOK)
  1042.         return NOTOK;
  1043.  
  1044.  
  1045.     if (build_drc_pr_fields (qp, recip, dr -> dr_recip_list,
  1046.                  &drc -> per__recipient__fields) == NOTOK)
  1047.         return NOTOK;
  1048.  
  1049.     return OK;
  1050. }
  1051.  
  1052. static int build_drc_pr_fields (qp, recip, rr, prp)
  1053. Q_struct *qp;
  1054. ADDR    *recip;
  1055. Rrinfo    *rr;
  1056. struct element_MTA_9 **prp;
  1057. {
  1058.     struct element_MTA_9 *prf;
  1059.     struct type_MTA_PerRecipientReportTransferFields *pr;
  1060.     ADDR    *ap;
  1061.  
  1062.     if (rr == NULL)
  1063.         return NULL;
  1064.     for (ap = qp -> Raddress; ap; ap = ap -> ad_next)
  1065.         if (ap -> ad_no == rr -> rr_recip)
  1066.             break;
  1067.     if (ap == NULLADDR)
  1068.         return build_drc_pr_fields (qp, recip, rr -> rr_next, prp);
  1069.  
  1070.     *prp = prf = (struct element_MTA_9 *) smalloc (sizeof *prf);
  1071.  
  1072.     prf -> next = NULL;
  1073.     prf -> PerRecipientReportTransferFields = pr =
  1074.         (struct type_MTA_PerRecipientReportTransferFields *)
  1075.             smalloc (sizeof *pr);
  1076.     bzero ((char *)pr, sizeof *pr);
  1077.  
  1078.     if (build_addrdn (ap -> ad_r400adr, ap -> ad_dn,
  1079.             &pr -> actual__recipient__name) == NOTOK)
  1080.         return NOTOK;
  1081.  
  1082.     pr -> originally__specified__recipient__number =
  1083.         (struct type_MTA_OriginallySpecifiedRecipientNumber *)
  1084.             smalloc (sizeof *pr ->
  1085.                  originally__specified__recipient__number);
  1086.     pr -> originally__specified__recipient__number -> parm =
  1087.         ap -> ad_extension;
  1088.  
  1089.     if (build_ri (ap -> ad_resp,
  1090.               ap -> ad_mtarreq,
  1091.               ap -> ad_usrreq,
  1092.               &pr -> per__recipient__indicators) == NOTOK)
  1093.         return NOTOK;
  1094.  
  1095.     if (build_lasttrace (rr,
  1096.                  &pr -> last__trace__information) == NOTOK)
  1097.         return NOTOK;
  1098.  
  1099.     if (rr -> rr_originally_intended_recip &&
  1100.         build_fullname (rr -> rr_originally_intended_recip,
  1101.                 &pr -> originally__intended__recipient__name) == NOTOK)
  1102.         return NOTOK;
  1103.  
  1104.     if (rr -> rr_supplementary) {
  1105.         if ((int) strlen(rr -> rr_supplementary) >
  1106.             UB_SUPPLEMENTARY_INFO_LENGTH)
  1107.             return setuberror ("Supplementary Information",
  1108.                        strlen(rr -> rr_supplementary),
  1109.                        UB_SUPPLEMENTARY_INFO_LENGTH,
  1110.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  1111.             
  1112.         if ((pr -> supplementary__information =
  1113.              STR2QB (rr -> rr_supplementary)) == NULL)
  1114.             return NOTOK;
  1115.     }
  1116.     if (build_drc_pr_extensions (qp, rr, &pr -> extensions) == NOTOK)
  1117.         return NOTOK;
  1118.  
  1119.     if (build_drc_pr_fields (qp, recip, rr -> rr_next,
  1120.                  &prf -> next) == NOTOK)
  1121.         return NOTOK;
  1122.  
  1123.     return OK;
  1124. }
  1125.  
  1126. static int build_lasttrace (rr, ltip)
  1127. Rrinfo *rr;
  1128. struct type_MTA_LastTraceInformation **ltip;
  1129. {
  1130.     struct type_MTA_LastTraceInformation *lti;
  1131.  
  1132.     *ltip = lti = (struct type_MTA_LastTraceInformation *)
  1133.         smalloc (sizeof *lti);
  1134.     bzero ((char *)lti, sizeof *lti);
  1135.  
  1136.     if (build_time (rr -> rr_arrival,
  1137.             <i -> arrival__time) == NOTOK)
  1138.         return NOTOK;
  1139.  
  1140.     if (rr -> rr_converted &&
  1141.         build_eits (rr -> rr_converted,
  1142.             <i -> converted__encoded__information__types) == NOTOK)
  1143.         return NOTOK;
  1144.  
  1145.     if (build_report (&rr -> rr_report,
  1146.               <i -> report) == NOTOK)
  1147.         return NOTOK;
  1148.  
  1149.     return OK;
  1150. }
  1151.  
  1152. static int build_report (rp, repp)
  1153. Report *rp;
  1154. struct type_MTA_Report **repp;
  1155. {
  1156.     struct type_MTA_Report *rep;
  1157.  
  1158.     *repp = rep = (struct type_MTA_Report *)
  1159.         smalloc (sizeof *rep);
  1160.  
  1161.     if (rp -> rep_type == DR_REP_SUCCESS) {
  1162.         struct type_MTA_DeliveryReport *drp;
  1163.  
  1164.         rep -> offset = type_MTA_Report_delivery;
  1165.  
  1166.         rep -> un.delivery = drp =
  1167.             (struct type_MTA_DeliveryReport *)
  1168.                 smalloc (sizeof *drp);
  1169.  
  1170.         if (build_time (rp->rep.rep_dinfo.del_time,
  1171.                 &drp -> message__delivery__time) == NOTOK)
  1172.             return NOTOK;
  1173.  
  1174.         if (rp -> rep.rep_dinfo.del_type > UB_MTS_USER_TYPES)
  1175.             return setuberror ("TypeOfMtsUser",
  1176.                     rp -> rep.rep_dinfo.del_type,
  1177.                     UB_MTS_USER_TYPES,
  1178.                     DRD_SIZE_CONSTRAINT_VIOLATION);
  1179.         drp -> type__of__MTS__user =
  1180.             (struct type_MTA_TypeOfMTSUser *)
  1181.                 smalloc (sizeof *drp -> type__of__MTS__user);
  1182.         drp -> type__of__MTS__user -> parm =
  1183.             rp -> rep.rep_dinfo.del_type;
  1184.     }
  1185.     else if (rp -> rep_type == DR_REP_FAILURE) {
  1186.         struct type_MTA_NonDeliveryReport *ndr;
  1187.  
  1188.         rep -> offset = type_MTA_Report_non__delivery;
  1189.  
  1190.         rep -> un.non__delivery = ndr =
  1191.             (struct type_MTA_NonDeliveryReport *)
  1192.                 smalloc (sizeof *ndr);
  1193.         if (rp -> rep.rep_ndinfo.nd_rcode > UB_REASON_CODES) 
  1194.             return setuberror ("Reason Code",
  1195.                        rp -> rep.rep_ndinfo.nd_rcode,
  1196.                        UB_REASON_CODES,
  1197.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  1198.         ndr -> non__delivery__reason__code =
  1199.             (struct type_MTA_NonDeliveryReasonCode *)
  1200.                 smalloc (sizeof *ndr -> non__delivery__reason__code);
  1201.         ndr -> non__delivery__reason__code -> parm =
  1202.             rp -> rep.rep_ndinfo.nd_rcode;
  1203.  
  1204.         if (rp -> rep.rep_ndinfo.nd_dcode > UB_DIAGNOSTIC_CODES)
  1205.             return setuberror ("Diagnostic code",
  1206.                        rp -> rep.rep_ndinfo.nd_dcode,
  1207.                        UB_DIAGNOSTIC_CODES,
  1208.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  1209.         ndr -> non__delivery__diagnostic__code =
  1210.             (struct type_MTA_NonDeliveryDiagnosticCode *)
  1211.                 smalloc (sizeof *ndr -> non__delivery__diagnostic__code);
  1212.         ndr -> non__delivery__diagnostic__code -> parm =
  1213.             rp -> rep.rep_ndinfo.nd_dcode;
  1214.     }
  1215.     else {
  1216.         PP_LOG (LLOG_EXCEPTIONS, ("Bad delivery report type %d",
  1217.                       rp -> rep_type));
  1218.         return NOTOK;
  1219.     }
  1220.  
  1221.     return OK;
  1222. }
  1223.  
  1224. static int build_fullname (fn, ornp)
  1225. FullName    *fn;
  1226. struct type_MTA_ORName **ornp;
  1227. {
  1228.     if (build_addrdn (fn -> fn_addr, fn -> fn_dn, ornp) == NOTOK)
  1229.         return NOTOK;
  1230.     return OK;
  1231. }
  1232.  
  1233.  
  1234. static int build_prb_recips (ad, adl, disclose, rlp)
  1235. ADDR    *ad;
  1236. ADDR    *adl;
  1237. int    disclose;
  1238. struct element_MTA_7 **rlp;
  1239. {
  1240.     struct element_MTA_7 *rl = NULL;
  1241.     struct type_MTA_PerRecipientProbeTransferFields *prmtf;
  1242.     ADDR    *ap, *ap2;
  1243.     int    resp;
  1244.     int naddr = 0;
  1245.  
  1246.     *rlp = NULL;
  1247.     for (ap = ad; ap; ap = ap -> ad_next) {
  1248.         for (ap2 = adl; ap2; ap2 = ap2 -> ad_next) {
  1249.             if (ap2 -> ad_no == ap -> ad_no)
  1250.                 break;
  1251.         }
  1252.         if (ap2 == NULLADDR)
  1253.             resp = FALSE;
  1254.         else
  1255.             resp = ap2 -> ad_resp;
  1256.                 
  1257.  
  1258.         if (*rlp == NULL) 
  1259.             *rlp = rl = (struct element_MTA_7 *)
  1260.                 smalloc (sizeof *rl);
  1261.         else {
  1262.             rl -> next = (struct element_MTA_7 *)
  1263.                 smalloc (sizeof *rl);
  1264.             rl = rl -> next;
  1265.         }
  1266.         bzero ((char *)rl, sizeof *rl);
  1267.         prmtf = rl -> PerRecipientProbeTransferFields =
  1268.             (struct type_MTA_PerRecipientProbeTransferFields *)
  1269.             smalloc (sizeof *prmtf);
  1270.  
  1271.         if (build_addrdn (ap -> ad_r400adr, ap -> ad_dn,
  1272.                 &prmtf -> recipient__name) == NOTOK)
  1273.             return NOTOK;
  1274.  
  1275.         prmtf -> originally__specified__recipient__number =
  1276.             (struct type_MTA_OriginallySpecifiedRecipientNumber *)
  1277.             smalloc (sizeof *prmtf ->
  1278.                  originally__specified__recipient__number);
  1279.         prmtf -> originally__specified__recipient__number -> parm =
  1280.             ap -> ad_extension;
  1281.  
  1282.         if (ap -> ad_explicitconversion != AD_EXP_NONE) {
  1283.             prmtf -> explicit__conversion =
  1284.                 (struct type_MTA_ExplicitConversion *)
  1285.                     smalloc (sizeof *prmtf -> explicit__conversion);
  1286.             prmtf -> explicit__conversion -> parm =
  1287.                 ap -> ad_explicitconversion;
  1288.         }
  1289.         else prmtf -> explicit__conversion = NULL;
  1290.  
  1291.         if (build_ri (resp,
  1292.                   ap -> ad_mtarreq,
  1293.                   ap -> ad_usrreq,
  1294.                   &prmtf -> per__recipient__indicators) == NOTOK)
  1295.             return NOTOK;
  1296.         if (build_prf_ext (ap,1,0,
  1297.                    &prmtf -> extensions) == NOTOK)
  1298.             return NOTOK;
  1299.         if (naddr++ > UB_RECIPIENTS)
  1300.             return setuberror("Max number of recipients", naddr,
  1301.                       UB_RECIPIENTS,
  1302.                       DRD_TOO_MANY_RECIPIENTS);
  1303.     }
  1304.     return OK;
  1305. }
  1306.  
  1307. static int build_p3_prb_recips (ad, rlp)
  1308. ADDR    *ad;
  1309. struct element_MTA_1 **rlp;
  1310. {
  1311.     struct element_MTA_1 *rl = NULL;
  1312.     struct type_MTA_PerRecipientProbeSubmissionFields *prmtf;
  1313.     ADDR    *ap;
  1314.  
  1315.     *rlp = NULL;
  1316.     for (ap = ad; ap; ap = ap -> ad_next) {
  1317.  
  1318.         if (*rlp == NULL) 
  1319.             *rlp = rl = (struct element_MTA_1 *)
  1320.                 smalloc (sizeof *rl);
  1321.         else {
  1322.             rl -> next = (struct element_MTA_1 *)
  1323.                 smalloc (sizeof *rl);
  1324.             rl = rl -> next;
  1325.         }
  1326.         bzero ((char *)rl, sizeof *rl);
  1327.         prmtf = rl -> PerRecipientProbeSubmissionFields =
  1328.             (struct type_MTA_PerRecipientProbeSubmissionFields *)
  1329.             smalloc (sizeof *prmtf);
  1330.  
  1331.         if (build_addrdn (ap -> ad_r400adr, ap -> ad_dn,
  1332.                 &prmtf -> recipient__name) == NOTOK)
  1333.             return NOTOK;
  1334.  
  1335.         if (ap -> ad_explicitconversion != AD_EXP_NONE) {
  1336.             prmtf -> explicit__conversion =
  1337.                 (struct type_MTA_ExplicitConversion *)
  1338.                     smalloc (sizeof *prmtf -> explicit__conversion);
  1339.             prmtf -> explicit__conversion -> parm =
  1340.                 ap -> ad_explicitconversion;
  1341.         }
  1342.         else prmtf -> explicit__conversion = NULL;
  1343.  
  1344.         if (build_p3_ri (ap -> ad_usrreq,
  1345.                  &prmtf     -> originator__report__request) == NOTOK)
  1346.             return NOTOK;
  1347.         if (build_prf_ext (ap,0,0,
  1348.                    &prmtf -> extensions) == NOTOK)
  1349.             return NOTOK;
  1350.     }
  1351.     return OK;
  1352. }
  1353.  
  1354. static int build_probe_envelope (qp, adl, prbp)
  1355. Q_struct *qp;
  1356. ADDR *adl;
  1357. struct type_MTA_ProbeTransferEnvelope **prbp;
  1358. {
  1359.     struct type_MTA_ProbeTransferEnvelope *prb;
  1360.  
  1361.     *prbp = prb = (struct type_MTA_ProbeTransferEnvelope *)
  1362.         smalloc (sizeof *prb);
  1363.     bzero ((char *)prb, sizeof *prb);
  1364.  
  1365.     if (build_msgid (&qp -> msgid, &prb -> probe__identifier ) == NOTOK)
  1366.         return NOTOK;
  1367.  
  1368.  
  1369.     if (build_addrdn (qp -> Oaddress -> ad_r400adr,
  1370.               qp -> Oaddress -> ad_dn,
  1371.               &prb -> originator__name) == NOTOK)
  1372.         return NOTOK;
  1373.  
  1374.     if (build_eits (&qp -> encodedinfo,
  1375.             &prb -> original__encoded__information__types) == NOTOK)
  1376.         return NOTOK;
  1377.  
  1378.     if (build_content (adl -> ad_content ?
  1379.                adl -> ad_content :
  1380.                qp -> cont_type,
  1381.                &prb -> member_MTA_15) == NOTOK)
  1382.         return NOTOK;
  1383.  
  1384.     if (qp -> ua_id) {
  1385.         if ((int) strlen(qp -> ua_id) > UB_CONTENT_ID_LENGTH)
  1386.             return setuberror ("Content Id", strlen(qp -> ua_id),
  1387.                     UB_CONTENT_ID_LENGTH,
  1388.                     DRD_SIZE_CONSTRAINT_VIOLATION);
  1389.         if ((prb -> content__identifier =
  1390.              STR2QB (qp -> ua_id)) == NULL)
  1391.             return NOTOK;
  1392.     }
  1393.     prb -> content__length = (struct type_MTA_ContentLength *)
  1394.         smalloc (sizeof *prb -> content__length);
  1395.     if (qp -> msgsize > UB_CONTENT_LENGTH)
  1396.         return setuberror ("MessageSize", qp -> msgsize,
  1397.                    UB_CONTENT_LENGTH,
  1398.                    DRD_SIZE_CONSTRAINT_VIOLATION);
  1399.  
  1400.     prb -> content__length -> parm = qp -> msgsize;
  1401.  
  1402.     if (build_pmf (qp,
  1403.                &prb -> per__message__indicators) == NOTOK)
  1404.         return NOTOK;
  1405.  
  1406.     prb -> per__domain__bilateral__information = NULL;
  1407.  
  1408.     if (build_trace (qp -> trace,
  1409.              &prb -> trace__information) == NOTOK)
  1410.         return NOTOK;
  1411.  
  1412.     if (build_pm_extensions (qp,1,0,
  1413.                  &prb -> extensions) == NOTOK)
  1414.         return NOTOK;
  1415.  
  1416.     if (build_prb_recips (qp -> disclose_recips ? qp -> Raddress : adl,
  1417.                   adl, qp -> disclose_recips,
  1418.                   &prb -> per__recipient__fields) == NOTOK)
  1419.         return NOTOK;
  1420.  
  1421.     return OK;
  1422. }
  1423.  
  1424. int build_p3_probe_envelope (qp, prbp)
  1425. Q_struct *qp;
  1426. struct type_MTA_ProbeSubmissionEnvelope **prbp;
  1427. {
  1428.     struct type_MTA_ProbeSubmissionEnvelope *prb;
  1429.  
  1430.     *prbp = prb = (struct type_MTA_ProbeSubmissionEnvelope *)
  1431.         smalloc (sizeof *prb);
  1432.     bzero ((char *)prb, sizeof *prb);
  1433.  
  1434.  
  1435.     if (build_addrdn (qp -> Oaddress -> ad_r400adr,
  1436.             qp -> Oaddress -> ad_dn,
  1437.             &prb -> originator__name) == NOTOK)
  1438.         return NOTOK;
  1439.  
  1440.     if (build_eits (&qp -> orig_encodedinfo,
  1441.             &prb -> original__eits) == NOTOK)
  1442.         return NOTOK;
  1443.  
  1444.     if (build_content (qp -> cont_type,
  1445.                &prb -> member_MTA_7) == NOTOK)
  1446.         return NOTOK;
  1447.  
  1448.     if (qp -> ua_id) {
  1449.         if ((int) strlen(qp -> ua_id) > UB_CONTENT_ID_LENGTH)
  1450.             return setuberror ("Content Id", strlen(qp -> ua_id),
  1451.                        UB_CONTENT_ID_LENGTH,
  1452.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  1453.  
  1454.         if ((prb -> content__identifier =
  1455.              STR2QB (qp -> ua_id)) == NULL)
  1456.         return NOTOK;
  1457.     }
  1458.     prb -> content__length = (struct type_MTA_ContentLength *)
  1459.         smalloc (sizeof *prb -> content__length);
  1460.     prb -> content__length -> parm = qp -> msgsize;
  1461.  
  1462.     if (build_pmf (qp,
  1463.                &prb -> per__message__indicators) == NOTOK)
  1464.         return NOTOK;
  1465.  
  1466.     if (build_pm_extensions (qp,0,0,
  1467.                  &prb -> extensions) == NOTOK)
  1468.         return NOTOK;
  1469.  
  1470.     if (build_p3_prb_recips (qp -> Raddress,
  1471.                  &prb -> per__recipient__fields) == NOTOK)
  1472.         return NOTOK;
  1473.  
  1474.     return OK;
  1475. }
  1476.  
  1477.  
  1478. /*   EXTENSIONS */
  1479.  
  1480. #define wrap_up_ext(e, n)    \
  1481.     (e) = (struct type_MTA_Extensions *) smalloc (sizeof *(e)); \
  1482.     (e) -> next = NULL; (e) -> ExtensionField = (n);
  1483. #define STR2QB(s)    str2qb(s, strlen(s), 1)
  1484.  
  1485.  
  1486. static int build_ext_type (ext_int, ext_oid, typep)
  1487. int    ext_int;
  1488. OID    ext_oid;
  1489. struct type_MTA_ExtensionType **typep;
  1490. {
  1491.     struct type_MTA_ExtensionType *type;
  1492.  
  1493.     *typep = type = (struct type_MTA_ExtensionType *)
  1494.         smalloc (sizeof *type);
  1495.  
  1496.     if (ext_int == EXT_OID_FORM) {
  1497.         type -> offset = type_MTA_ExtensionType_local;
  1498.         if ((type -> un.local = oid_cpy (ext_oid)) == NULLOID)
  1499.             return NOTOK;
  1500.     } else {
  1501.         type -> offset = type_MTA_ExtensionType_global;
  1502.         if (ext_int > UB_EXTENSION_TYPES) 
  1503.             return setuberror ("Extension types",
  1504.                        ext_int, UB_EXTENSION_TYPES,
  1505.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  1506.  
  1507.         type -> un.global = ext_int;
  1508.     }
  1509.     return OK;
  1510. }
  1511.  
  1512. static int build_crit (cr, crp)
  1513. int    cr;
  1514. struct type_MTA_Criticality **crp;
  1515. {
  1516.     char    *p;
  1517.     int nbits = 3;
  1518.  
  1519.     if (cr > (1<<UB_BIT_OPTIONS))
  1520.         return setuberror ("Criticality", cr, UB_BIT_OPTIONS,
  1521.                    DRD_SIZE_CONSTRAINT_VIOLATION);
  1522.  
  1523.     if (cr > 7) {
  1524.         nbits = UB_BIT_OPTIONS;
  1525.     }
  1526.     p = int2strb (cr, nbits);
  1527.     *crp = strb2bitstr (p, nbits, PE_CLASS_UNIV, PE_PRIM_BITS);
  1528.     if (*crp == NULL)
  1529.         return NOTOK;
  1530.     return OK;
  1531. }
  1532.  
  1533. static int    build_ext_value (qb, pep)
  1534. struct qbuf *qb;
  1535. PE    *pep;
  1536. {
  1537.     char    *cp;
  1538.     PS    ps;
  1539.  
  1540.     cp = qb2str(qb);
  1541.  
  1542.     if ((ps = ps_alloc (str_open)) == NULLPS) {
  1543.         PP_LOG (LLOG_EXCEPTIONS, ("PS alloc failed"));
  1544.         return NOTOK;
  1545.     }
  1546.  
  1547.     if (str_setup (ps, cp, qb -> qb_len, 1) == NOTOK) {
  1548.         PP_LOG (LLOG_EXCEPTIONS, ("Can't setup PS stream"));
  1549.         return NOTOK;
  1550.     }
  1551.  
  1552.     if ((*pep = ps2pe (ps)) == NULLPE) {
  1553.         PP_LOG (LLOG_EXCEPTIONS, ("ps2pe failed [%s]",
  1554.                       ps_error (ps -> ps_errno)));
  1555.         return NOTOK;
  1556.     }
  1557.     ps_free (ps);
  1558.     return OK;
  1559. }    
  1560.  
  1561. static int build_ext_generic (parm, crit, defcrit, type, oid, mod_idx,
  1562.                   mod, fnx, label, extlp)
  1563. caddr_t parm;
  1564. int crit;
  1565. int type;
  1566. int defcrit;
  1567. OID    oid;
  1568. int mod_idx;
  1569. modtyp *mod;
  1570. IFP    fnx;
  1571. char *label;
  1572. struct type_MTA_Extensions **extlp;
  1573. {
  1574.     struct type_MTA_ExtensionField *ext;
  1575.     caddr_t value;
  1576.  
  1577.     ext = (struct type_MTA_ExtensionField *)
  1578.         smalloc (sizeof *ext);
  1579.     if (build_ext_type (type, oid, &ext -> type) == NOTOK)
  1580.         return NOTOK;
  1581.     if (crit != defcrit) {
  1582.         if (build_crit (crit, &ext -> criticality) == NOTOK)
  1583.             return NOTOK;
  1584.     }
  1585.     else ext -> criticality = NULL;
  1586.  
  1587.     if ((*fnx) (&value, parm) == NOTOK)
  1588.         return NOTOK;
  1589.  
  1590.     if (enc_f (mod_idx, mod, &ext -> value, 1, 0, NULLCP, value)
  1591.         == NOTOK) {
  1592.         PP_LOG (LLOG_EXCEPTIONS, ("Can't encode value %s: %s",
  1593.                       label, PY_pepy));
  1594.         return NOTOK;
  1595.     }
  1596.  
  1597. #if PP_DEBUG > 0
  1598.     if(pp_log_norm -> ll_events & LLOG_PDUS) 
  1599.         pvpdu (pp_log_norm, mod_idx, mod,
  1600.                ext -> value, label, PDU_WRITE);
  1601. #endif
  1602.     fre_obj (value, mod->md_dtab[mod_idx], mod, 1);
  1603.  
  1604.     *extlp = (struct type_MTA_Extensions *) smalloc (sizeof **extlp);
  1605.     (*extlp) -> next = NULL;
  1606.     (*extlp) -> ExtensionField = ext;
  1607.     return OK;
  1608. }
  1609.  
  1610. static int build_ext_int (value, parm)
  1611. caddr_t *value;
  1612. caddr_t parm;
  1613. {
  1614.     int *ip = (int *)parm;
  1615.     struct type_Ext_RecipientReassignmentProhibited **val =
  1616.         (struct type_Ext_RecipientReassignmentProhibited **) value;
  1617.  
  1618.     *val = (struct type_Ext_RecipientReassignmentProhibited *)
  1619.         smalloc (sizeof **val);
  1620.     (*val) -> parm = *ip;
  1621.     return OK;
  1622. }
  1623.  
  1624. static int build_ext_char (value, parm)
  1625. caddr_t *value;
  1626. caddr_t parm;
  1627. {
  1628.     char *cp = (char *)parm;
  1629.     struct type_Ext_RecipientReassignmentProhibited **val =
  1630.         (struct type_Ext_RecipientReassignmentProhibited **) value;
  1631.  
  1632.     *val = (struct type_Ext_RecipientReassignmentProhibited *)
  1633.         smalloc (sizeof **val);
  1634.     (*val) -> parm = *cp;
  1635.     return OK;
  1636. }
  1637.  
  1638. static int build_ext_time (value, parm)
  1639. caddr_t    *value;
  1640. caddr_t parm;
  1641. {
  1642.     UTC utc = (UTC)parm;
  1643.     struct type_UNIV_UTCTime **ut = (struct type_UNIV_UTCTime **)value;
  1644.     return build_time (utc, ut);
  1645. }
  1646.  
  1647. static int build_ext_dlh (value, parm)
  1648. caddr_t *value;
  1649. caddr_t parm;
  1650. {
  1651.     DLHistory *dlp = (DLHistory *)parm;
  1652.     struct type_Ext_DLExpansionHistory **val =
  1653.         (struct type_Ext_DLExpansionHistory **)value;
  1654.     return build_dehl (dlp, val);
  1655. }
  1656.  
  1657. static int build_aext_oraa (value, parm)
  1658. caddr_t *value;
  1659. caddr_t parm;
  1660. {
  1661.     char *ora = (char *)parm;
  1662.     struct type_MTA_ORName **val = (struct type_MTA_ORName **)value;
  1663.  
  1664.     return build_addrdn (ora, NULLCP, val);
  1665. }
  1666.  
  1667. static int build_aext_rdm (value, parm)
  1668. caddr_t *value;
  1669. caddr_t parm;
  1670. {
  1671.     char *rdm = (char *)parm;
  1672.     struct type_Ext_RequestedDeliveryMethod **val =
  1673.         (struct type_Ext_RequestedDeliveryMethod **)value;
  1674.     int    i;
  1675.  
  1676.     *val = NULL;
  1677.  
  1678.     for (i = 0; i < AD_RDM_MAX && rdm[i] != AD_RDM_NOTUSED; i++) {
  1679.         *val = (struct type_Ext_RequestedDeliveryMethod *)
  1680.             smalloc (sizeof **val);
  1681.         (*val) -> element_Ext_0 = parm[i];
  1682.         (*val) -> next = NULL;
  1683.         val = &(*val) -> next;
  1684.     }
  1685.  
  1686.     return OK;
  1687. }
  1688. static int build_aext_pra (value, parm)
  1689. caddr_t *value;
  1690. caddr_t parm;
  1691. {
  1692.     struct type_Ext_PhysicalRenditionAttributes **val =
  1693.         (struct type_Ext_PhysicalRenditionAttributes **)value;
  1694.     OID pra = (OID)parm;
  1695.  
  1696.     if ((*val = oid_cpy (pra)) == NULLOID)
  1697.         return NOTOK;
  1698.     return OK;
  1699. }
  1700.  
  1701. static int build_aext_pdm (value, parm)
  1702. caddr_t *value;
  1703. caddr_t parm;
  1704. {
  1705.     int *pdm = (int *)parm;
  1706.     struct type_Ext_PhysicalDeliveryModes **val =
  1707.         (struct type_Ext_PhysicalDeliveryModes **)value;
  1708.     char    *p;
  1709.  
  1710.     p = int2strb (*pdm, 8);
  1711.     if ((*val = strb2bitstr (p, 8, PE_CLASS_UNIV, PE_PRIM_BITS)) == NULLPE)
  1712.         return NOTOK;
  1713.     return OK;
  1714. }
  1715.  
  1716. static int build_aext_rnfa (value, parm)
  1717. caddr_t *value;
  1718. caddr_t parm;
  1719. {
  1720.     char *rnfa = (char *)parm;
  1721.     struct type_Ext_RecipientNumberForAdvice **val =
  1722.         (struct type_Ext_RecipientNumberForAdvice **)value;;
  1723.  
  1724.     if ((int) strlen(rnfa) > UB_RECIPIENT_NUMBER_FOR_ADVICE_LENGTH)
  1725.         return setuberror ("RecipientNumberForAdvice",
  1726.                 strlen(rnfa),
  1727.                 UB_RECIPIENT_NUMBER_FOR_ADVICE_LENGTH,
  1728.                 DRD_SIZE_CONSTRAINT_VIOLATION);
  1729.  
  1730.     if ((*val = STR2QB (rnfa)) == NULL)
  1731.         return NOTOK;
  1732.     return OK;
  1733. }
  1734.  
  1735. static int build_aext_redir (value, parm)
  1736. caddr_t *value;
  1737. caddr_t parm;
  1738. {
  1739.     Redirection *redir = (Redirection *)parm;
  1740.     struct type_Ext_RedirectionHistory  **rp =
  1741.         (struct type_Ext_RedirectionHistory **)value;
  1742.     struct type_Ext_Redirection *rd;
  1743.     int nredir = 0;
  1744.  
  1745.     *rp = NULL;
  1746.     for ( ; redir; redir = redir -> rd_next) {
  1747.         *rp = (struct type_Ext_RedirectionHistory *)
  1748.             smalloc (sizeof **rp);
  1749.         (*rp) -> next = NULL;
  1750.         (*rp) -> Redirection = rd =
  1751.             (struct type_Ext_Redirection *)
  1752.                 smalloc (sizeof *rd);
  1753.         rd -> intended__recipient__name =
  1754.             (struct type_Ext_IntendedRecipientName *)
  1755.                 smalloc (sizeof *rd -> intended__recipient__name);
  1756.         
  1757.         if (build_addrdn (redir -> rd_addr, redir -> rd_dn,
  1758.                 &rd -> intended__recipient__name -> address) == NOTOK)
  1759.             return NOTOK;
  1760.         
  1761.         if (build_time (redir -> rd_time,
  1762.                 &rd -> intended__recipient__name -> redirection__time) == NOTOK)
  1763.             return NOTOK;
  1764.  
  1765.         rd -> redirection__reason =
  1766.             (struct type_Ext_RedirectionReason *)
  1767.                 smalloc (sizeof *rd -> redirection__reason);
  1768.         rd -> redirection__reason -> parm = redir -> rd_reason;
  1769.         
  1770.         if (++nredir > UB_REDIRECTIONS)
  1771.             return setuberror ("RedirectionHistory",
  1772.                     nredir, UB_REDIRECTIONS,
  1773.                     DRD_SIZE_CONSTRAINT_VIOLATION);
  1774.     }
  1775.     return OK;
  1776. }
  1777.  
  1778. static int build_ext_ora (value, parm)
  1779. caddr_t *value;
  1780. caddr_t parm;
  1781. {
  1782.     struct type_Ext_OriginatorReturnAddress **val =
  1783.         (struct type_Ext_OriginatorReturnAddress **)value;
  1784.     char *ora = (char *)parm;
  1785.  
  1786.     return build_addr (ora, val);
  1787. }
  1788.  
  1789. static int build_ext_fn (value, parm)
  1790. caddr_t *value;
  1791. caddr_t parm;
  1792. {
  1793.     FullName *fn = (FullName *)parm;
  1794.     struct type_MTA_ORName **orn =
  1795.         (struct type_MTA_ORName **)value;
  1796.     return build_fullname (fn, orn);
  1797. }
  1798.  
  1799. static int build_ext_secure (parm, crit, defcrit, type, oid,
  1800.                  modid, mod, label, extlp)
  1801. struct qbuf    *parm;
  1802. int    crit;
  1803. int defcrit;
  1804. int type;
  1805. OID oid;
  1806. int modid;
  1807. modtyp *mod;
  1808. char *label;
  1809. struct type_MTA_Extensions **extlp;
  1810. {
  1811.     struct type_MTA_ExtensionField *ext;
  1812.  
  1813.     ext = (struct type_MTA_ExtensionField *) smalloc (sizeof *ext);
  1814.  
  1815.     if (build_ext_type (type, oid, &ext -> type) == NOTOK)
  1816.         return NOTOK;
  1817.  
  1818.     if (crit != defcrit) {
  1819.         if (build_crit (crit, &ext -> criticality) == NOTOK)
  1820.             return NOTOK;
  1821.     }
  1822.     else
  1823.         ext -> criticality = NULL;
  1824.  
  1825.     
  1826.     if (build_ext_value (parm, &ext -> value) == NOTOK)
  1827.         return NOTOK;
  1828.  
  1829. #if PP_DEBUG > 0
  1830.     if(pp_log_norm -> ll_events & LLOG_PDUS) 
  1831.         pvpdu (pp_log_norm, modid, mod,
  1832.                ext -> value, label, PDU_WRITE);
  1833. #endif
  1834.     *extlp = (struct type_MTA_Extensions *) smalloc (sizeof **extlp);
  1835.     (*extlp) -> next = NULL;
  1836.     (*extlp) -> ExtensionField = ext;
  1837.     return OK;
  1838. }
  1839.  
  1840.  
  1841.  
  1842. static int build_dehl (dlh, dlp)
  1843. DLHistory *dlh;
  1844. struct type_Ext_DLExpansionHistory **dlp;
  1845. {
  1846.     struct type_Ext_DLExpansionHistory **dp;
  1847.     struct type_Ext_DLExpansion *d;
  1848.     int ndlexp = 0;
  1849.  
  1850.     *dlp = NULL;
  1851.     dp = dlp;
  1852.     for (;dlh; dlh = dlh -> dlh_next) {
  1853.         *dp = (struct type_Ext_DLExpansionHistory *)
  1854.             smalloc (sizeof **dp);
  1855.         (*dp) -> next = NULL;
  1856.         d = (*dp) -> DLExpansion =
  1857.             (struct type_Ext_DLExpansion *)
  1858.                 smalloc (sizeof *d);
  1859.  
  1860.         if (build_addrdn (dlh -> dlh_addr,
  1861.                   dlh -> dlh_dn,
  1862.                   &d -> address) == NOTOK)
  1863.             return NOTOK;
  1864.  
  1865.         if (build_time (dlh -> dlh_time,
  1866.                 &d -> dl__expansion__time) == NOTOK)
  1867.             return NOTOK;
  1868.  
  1869.         dp = &(*dp) -> next;
  1870.         if (++ ndlexp > UB_DL_EXPANSIONS)
  1871.             return setuberror ("DLexpansionHistory",
  1872.                     ndlexp, UB_DL_EXPANSIONS,
  1873.                     DRD_SIZE_CONSTRAINT_VIOLATION);
  1874.     }
  1875.     return OK;
  1876. }
  1877.     
  1878.  
  1879. static int build_msi (dp, msip)
  1880. DomSupInfo *dp;
  1881. struct type_Ext_MTASuppliedInformation **msip;
  1882. {
  1883.     struct type_Ext_MTASuppliedInformation *msi;
  1884.  
  1885.     *msip = msi = (struct type_Ext_MTASuppliedInformation *)
  1886.         smalloc(sizeof *msi);
  1887.     bzero ((char *)msi, sizeof *msi);
  1888.  
  1889.     if (dp -> dsi_time)
  1890.         if (build_time (dp -> dsi_time,
  1891.                 &msi -> arrival__time) == NOTOK)
  1892.             return NOTOK;
  1893.     msi -> routing__action = (struct type_MTA_RoutingAction *)
  1894.         smalloc (sizeof *msi -> routing__action);
  1895.     msi -> routing__action -> parm = dp -> dsi_action;
  1896.  
  1897.     if (dp -> dsi_attempted_mta ||
  1898.         (dp -> dsi_attempted_md.global_Country &&
  1899.          dp -> dsi_attempted_md.global_Admin)) {
  1900.         msi -> attempted = (struct choice_Ext_1 *)
  1901.             calloc (1, sizeof *msi -> attempted);
  1902.         if (dp -> dsi_attempted_mta) {
  1903.             msi -> attempted -> offset =
  1904.                 choice_Ext_1_mta;
  1905.             if ((msi -> attempted -> un.mta =
  1906.                  STR2QB (dp -> dsi_attempted_mta)) == NULL)
  1907.                 return NOTOK;
  1908.         }
  1909.         else {
  1910.             msi -> attempted -> offset =
  1911.                 choice_Ext_1_domain;
  1912.             
  1913.             if (build_gdi (&dp -> dsi_attempted_md,
  1914.                        &msi -> attempted -> un.domain) == NOTOK)
  1915.                 return NOTOK;
  1916.         }
  1917.     }
  1918.  
  1919.     if (dp -> dsi_deferred &&
  1920.         build_time (dp -> dsi_deferred,
  1921.             &msi -> deferred__time) == NOTOK)
  1922.         return NOTOK;
  1923.     if (dp -> dsi_other_actions) {
  1924.         if ((msi -> other__actions =
  1925.              pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM,
  1926.                    PE_PRIM_BITS)) == NULLPE)
  1927.             return NOTOK;
  1928.         if ((dp -> dsi_other_actions & ACTION_REDIRECTED) &&
  1929.             bit_on (msi -> other__actions,
  1930.                 bit_MTA_OtherActions_redirected) == NOTOK)
  1931.             return NOTOK;
  1932.         if ((dp -> dsi_other_actions & ACTION_EXPANDED) &&
  1933.             bit_on (msi -> other__actions,
  1934.                 bit_MTA_OtherActions_dl__operation) == NOTOK)
  1935.             return NOTOK;
  1936.     }
  1937.     return OK;
  1938. }
  1939.  
  1940.  
  1941. static int build_inttrace (tp, tlp)
  1942. Trace    *tp;
  1943. struct type_Ext_InternalTraceInformation **tlp;
  1944. {
  1945.     struct type_Ext_InternalTraceInformation **tpp;
  1946.     struct type_Ext_InternalTraceInformationElement *ti;
  1947.     Trace    *tlast;
  1948.  
  1949.     *tlp = NULL;
  1950.     if (trace_type == RTSP_TRACE_ADMD ||
  1951.         trace_type == RTSP_TRACE_NOINT)
  1952.         return NULL;
  1953.  
  1954.     for (tlast = tp; tlast && tlast -> trace_next;
  1955.          tlast = tlast -> trace_next)
  1956.         continue;
  1957.  
  1958.     tpp = tlp;
  1959.     for (; tp; tp = tp -> trace_next) {
  1960.         if (tp -> trace_mta == NULLCP)
  1961.             continue;
  1962.         if (trace_type == RTSP_TRACE_LOCALINT &&
  1963.             !same_prmd (tlast, tp))
  1964.             continue;
  1965.  
  1966.         *tpp = (struct type_Ext_InternalTraceInformation *)
  1967.             smalloc (sizeof **tpp);
  1968.         (*tpp) -> next = NULL;
  1969.         ti = (*tpp) -> InternalTraceInformationElement =
  1970.             (struct type_Ext_InternalTraceInformationElement *)
  1971.                 calloc (1, sizeof *ti);
  1972.         
  1973.         if (build_gdi (&tp -> trace_DomId,
  1974.                    &ti -> global__domain__identifier) == NOTOK)
  1975.             return NOTOK;
  1976.         if ((ti -> mta__name = STR2QB (tp -> trace_mta)) == NULL)
  1977.             return NOTOK;
  1978.  
  1979.         
  1980.         if (build_msi (&tp -> trace_DomSinfo,
  1981.                    &ti -> mta__supplied__information) == NOTOK)
  1982.             return NOTOK;
  1983.         tpp = &(*tpp) -> next;
  1984.     }
  1985.     return OK;
  1986. }
  1987.  
  1988. static int build_ext_iti (parm, crit, extlp)
  1989. Trace    *parm;
  1990. char    crit;
  1991. struct type_MTA_Extensions **extlp;
  1992. {
  1993.     struct type_MTA_ExtensionField *ext;
  1994.     struct type_Ext_InternalTraceInformation *value;
  1995.  
  1996.     if(build_inttrace (parm, &value) == NOTOK)
  1997.         return NOTOK;
  1998.  
  1999.     ext = (struct type_MTA_ExtensionField *) smalloc (sizeof *ext);
  2000.  
  2001.     if (build_ext_type (EXT_INTERNAL_TRACE_INFORMATION,
  2002.                 NULLOID,
  2003.                 &ext -> type) == NOTOK)
  2004.         return NOTOK;
  2005.  
  2006.     if (crit != EXT_INTERNAL_TRACE_INFORMATION_DC) {
  2007.         if (build_crit (crit,
  2008.                 &ext -> criticality) == NOTOK)
  2009.             return NOTOK;
  2010.     }
  2011.     else
  2012.         ext -> criticality = NULL;
  2013.  
  2014.  
  2015.     if (encode_Ext_InternalTraceInformation
  2016.         (&ext -> value, 1, 0, NULLCP, value) == NOTOK) {
  2017.         PP_LOG (LLOG_EXCEPTIONS,
  2018.             ("Can't encode InternalTraceInformation value [%s]",
  2019.              PY_pepy));
  2020.         return NOTOK;
  2021.     }
  2022.  
  2023.     PP_PDUP (Ext_InternalTraceInformation,
  2024.         ext -> value, "Extensions.InternalTraceInformation",
  2025.         PDU_WRITE);
  2026.  
  2027.     free_Ext_InternalTraceInformation (value);
  2028.  
  2029.     wrap_up_ext (*extlp, ext);
  2030.     return OK;
  2031. }
  2032.  
  2033.  
  2034.  
  2035.  
  2036. static int build_extension (ext, epp)
  2037. X400_Extension *ext;
  2038. struct type_MTA_ExtensionField **epp;
  2039. {
  2040.     struct type_MTA_ExtensionField *ep;
  2041.  
  2042.     *epp = ep = (struct type_MTA_ExtensionField *) smalloc (sizeof *ep);
  2043.     if (build_ext_type (ext -> ext_int, ext -> ext_oid,
  2044.                 &ep -> type) == NOTOK)
  2045.         return NOTOK;
  2046.     if (build_crit (ext -> ext_criticality, &ep -> criticality) == NOTOK)
  2047.         return NOTOK;
  2048.     if (build_ext_value (ext -> ext_value, &ep -> value) == NOTOK)
  2049.         return NOTOK;
  2050.     return OK;
  2051. }
  2052.  
  2053. static int build_gen_extensions (xp, extp)
  2054. X400_Extension *xp;
  2055. struct type_MTA_Extensions **extp;
  2056. {
  2057.     for (;xp; xp = xp -> ext_next) {
  2058.         *extp = (struct type_MTA_Extensions *)
  2059.                 smalloc (sizeof **extp);
  2060.         (*extp) -> next = NULL;
  2061.         if (build_extension (xp,
  2062.                      &(*extp) -> ExtensionField) == NOTOK)
  2063.             return NOTOK;
  2064.         extp = &(*extp) -> next;
  2065.     }
  2066.     return OK;
  2067. }
  2068.  
  2069. static int build_pm_extensions (qp,p1,msg, extp)
  2070. Q_struct *qp;
  2071. int p1,msg;
  2072. struct type_MTA_Extensions **extp;
  2073. {
  2074.     struct type_MTA_Extensions **ep;
  2075.  
  2076.     *extp = NULL;
  2077.  
  2078.     if (build_gen_extensions (qp -> per_message_extensions, extp) == NOTOK)
  2079.         return NOTOK;
  2080.  
  2081.     for (ep = extp; *ep; ep = &(*ep) -> next)
  2082.         continue;
  2083.  
  2084.     if (qp -> recip_reassign_prohibited) {
  2085.         if (build_ext_generic (&qp -> recip_reassign_prohibited,
  2086.                        qp -> recip_reassign_crit,
  2087.                        EXT_RECIPIENT_REASSIGNMENT_PROHIBITED_DC,
  2088.                        EXT_RECIPIENT_REASSIGNMENT_PROHIBITED,
  2089.                        NULLOID,
  2090.                        _ZRecipientReassignmentProhibitedExt,
  2091.                        &_ZExt_mod,
  2092.                        build_ext_char,
  2093.                        "Extension.RecipientReassignmentProhibited",
  2094.                        ep) == NOTOK)
  2095.             return NOTOK;
  2096.         if (*ep)
  2097.             ep = &(*ep) -> next;
  2098.     }
  2099.     if (qp -> dl_expansion_prohibited) {
  2100.         if (build_ext_generic (&qp -> dl_expansion_prohibited,
  2101.                        qp -> dl_expansion_crit,
  2102.                        EXT_DL_EXPANSION_PROHIBITED_DC,
  2103.                        EXT_DL_EXPANSION_PROHIBITED,
  2104.                        NULLOID,
  2105.                        _ZDLExpansionProhibitedExt,
  2106.                        &_ZExt_mod,
  2107.                        build_ext_char,
  2108.                        "Extension.DLExpansionHistory",
  2109.                        ep) == NOTOK)
  2110.             return NOTOK;
  2111.         if (*ep)
  2112.             ep = &(*ep) -> next;
  2113.     }
  2114.     if (qp -> conversion_with_loss_prohibited) {
  2115.         if (build_ext_generic (&qp -> conversion_with_loss_prohibited,
  2116.                        qp -> conversion_with_loss_crit,
  2117.                        EXT_CONVERSION_WITH_LOSS_PROHIBITED_DC,
  2118.                        EXT_CONVERSION_WITH_LOSS_PROHIBITED,
  2119.                        NULLOID,
  2120.                        _ZConversionWithLossProhibitedExt,
  2121.                        &_ZExt_mod,
  2122.                        build_ext_char,
  2123.                        "Extension.ConversionWithLossProhibited",
  2124.                        ep) == NOTOK)
  2125.             return NOTOK;
  2126.         if (*ep)
  2127.             ep = &(*ep) -> next;
  2128.     }
  2129.     if (qp -> originator_certificate) {
  2130.         if (build_ext_secure (qp -> originator_certificate,
  2131.                       qp -> originator_certificate_crit,
  2132.                       EXT_ORIGINATOR_CERTIFICATE_DC,
  2133.                       EXT_ORIGINATOR_CERTIFICATE,
  2134.                       NULLOID,
  2135.                       _ZOriginatorCertificateExt,
  2136.                       &_ZExt_mod,
  2137.                       "Extensions.OriginatorCertificate",
  2138.                       ep) == NOTOK)
  2139.             return NOTOK;
  2140.         if (*ep)
  2141.             ep = &(*ep) -> next;
  2142.     }
  2143.     if (qp -> security_label) {
  2144.         if (build_ext_secure (qp -> security_label,
  2145.                       qp -> security_label_crit,
  2146.                       EXT_MESSAGE_SECURITY_LABEL_DC,
  2147.                       EXT_MESSAGE_SECURITY_LABEL,
  2148.                       NULLOID,
  2149.                       _ZMessageSecurityLabelExt,
  2150.                       &_ZExt_mod,
  2151.                       "Extensions.MessageSecurityLabel",
  2152.                       ep) == NOTOK)
  2153.             return NOTOK;
  2154.         if (*ep)
  2155.             ep = &(*ep) -> next;
  2156.     }
  2157.     if (qp -> general_content_correlator) {
  2158.         if (build_ext_secure (qp -> general_content_correlator,
  2159.                     qp -> content_correlator_crit,
  2160.                     EXT_CONTENT_CORRELATOR_DC,
  2161.                     EXT_CONTENT_CORRELATOR,
  2162.                     NULLOID,
  2163.                     _ZContentCorrelatorExt,
  2164.                     &_ZExt_mod,
  2165.                     "Extensions.ContentCorrelator",
  2166.                     ep) == NOTOK)
  2167.             return NOTOK;
  2168.         if (*ep &&
  2169.             ps_get_abs ((*ep) -> ExtensionField -> value) >
  2170.             UB_CONTENT_CORRELATOR_LENGTH)
  2171.             return setuberror ("ContentCorrelator",
  2172.                     ps_get_abs ((*ep) -> ExtensionField -> value),
  2173.                     UB_CONTENT_CORRELATOR_LENGTH,
  2174.                     DRD_SIZE_CONSTRAINT_VIOLATION);
  2175.         if (*ep)
  2176.             ep = &(*ep) -> next;
  2177.     }
  2178.     if (msg) {
  2179.         if (qp -> latest_time) {
  2180.             if (build_ext_generic ((caddr_t)qp -> latest_time,
  2181.                            qp -> latest_time_crit,
  2182.                            EXT_LATEST_DELIVERY_TIME_DC,
  2183.                            EXT_LATEST_DELIVERY_TIME,
  2184.                            NULLOID,
  2185.                            _ZLatestDeliveryTimeExt,
  2186.                            &_ZExt_mod,
  2187.                            build_ext_time,
  2188.                            "Extensions.LatestDeliveryTime",
  2189.                            ep) == NOTOK)
  2190.                 return NOTOK;
  2191.             if (*ep)
  2192.                 ep = &(*ep) -> next;
  2193.         }
  2194.         if (qp -> originator_return_address) {
  2195.             if (build_ext_generic
  2196.                 ((caddr_t)qp -> originator_return_address,
  2197.                  qp -> originator_return_address_crit,
  2198.                  EXT_ORIGINATOR_RETURN_ADDRESS_DC,
  2199.                  EXT_ORIGINATOR_RETURN_ADDRESS,
  2200.                  NULLOID,
  2201.                  _ZOriginatorReturnAddressExt,
  2202.                  &_ZExt_mod,
  2203.                  build_ext_ora,
  2204.                  "Extensions.OriginatorReturnAddress",
  2205.                  ep) == NOTOK)
  2206.                 return NOTOK;
  2207.             if (*ep)
  2208.                 ep = &(*ep) -> next;
  2209.         }
  2210.         if (qp -> algorithm_identifier) {
  2211.             if (build_ext_secure
  2212.                 (qp -> algorithm_identifier,
  2213.                  qp -> algorithm_identifier_crit,
  2214.                  EXT_CONTENT_CONFIDENTIALITY_ALGORITHM_IDENTIFIER_DC,
  2215.                  EXT_CONTENT_CONFIDENTIALITY_ALGORITHM_IDENTIFIER,
  2216.                  NULLOID,
  2217.                  _ZContentConfidentialityAlgorithmIdentifierExt,
  2218.                  &_ZExt_mod,
  2219.                  "Extensions.ContentConfidentialityAlgorithmIdentifier",
  2220.                  ep) == NOTOK)
  2221.                 return NOTOK;
  2222.             if (*ep)
  2223.                 ep = &(*ep) -> next;
  2224.         }
  2225.         if (qp -> message_origin_auth_check) {
  2226.             if (build_ext_secure (qp -> message_origin_auth_check,
  2227.                         qp -> message_origin_auth_check_crit,
  2228.                         EXT_MESSAGE_ORIGIN_AUTHENTICATION_CHECK_DC,
  2229.                         EXT_MESSAGE_ORIGIN_AUTHENTICATION_CHECK,
  2230.                         NULLOID,
  2231.                         _ZMessageOriginAuthenticationCheckExt,
  2232.                         &_ZExt_mod,
  2233.                         "Extensions.MessageOriginAuthenticationCheck",
  2234.                         ep) == NOTOK)
  2235.                 return NOTOK;
  2236.             if (*ep)
  2237.                 ep = &(*ep) -> next;
  2238.         }
  2239.     }
  2240.     if (!msg) {
  2241.         if (qp -> message_origin_auth_check) {
  2242.             if (build_ext_secure
  2243.                 (qp -> message_origin_auth_check,
  2244.                  qp -> message_origin_auth_check_crit,
  2245.                  EXT_PROBE_ORIGIN_AUTHENTICATION_CHECK_DC,
  2246.                  EXT_PROBE_ORIGIN_AUTHENTICATION_CHECK,
  2247.                  NULLOID,
  2248.                  _ZProbeOriginAuthenticationCheckExt,
  2249.                  &_ZExt_mod,
  2250.                  "Extensions.ProbeOriginAuthenticationCheck",
  2251.                  ep) == NOTOK)
  2252.                 return NOTOK;
  2253.             if (*ep)
  2254.                 ep = &(*ep) -> next;
  2255.         }
  2256.     }
  2257.     if (p1) {
  2258.         if (qp -> dl_expansion_history) {
  2259.             if (build_ext_generic
  2260.                 ((caddr_t)qp -> dl_expansion_history,
  2261.                  qp -> dl_expansion_history_crit,
  2262.                  EXT_DL_EXPANSION_HISTORY_DC,
  2263.                  EXT_DL_EXPANSION_HISTORY,
  2264.                  NULLOID,
  2265.                  _ZDLExpansionHistoryExt,
  2266.                  &_ZExt_mod,
  2267.                  build_ext_dlh,
  2268.                  "Extensions.DLExpansionHistory",
  2269.                  ep) == NOTOK)
  2270.                 return NOTOK;
  2271.             if (*ep)
  2272.                 ep = &(*ep) -> next;
  2273.         }
  2274.     
  2275.         if (qp -> trace) {
  2276.             if (build_ext_iti (qp -> trace,
  2277.                        EXT_INTERNAL_TRACE_INFORMATION_DC,
  2278.                        ep) == NOTOK)
  2279.                 return NOTOK;
  2280.             if (*ep)
  2281.                 ep = &(*ep) -> next;
  2282.         }
  2283.     }
  2284.     if ((!p1) && msg) {
  2285.         if (qp -> forwarding_request != NOTOK) {
  2286.             if (build_ext_generic
  2287.                 ((caddr_t)&qp -> forwarding_request,
  2288.                  qp -> forwarding_request_crit,
  2289.                  EXT_FORWARDING_REQUEST_DC,
  2290.                  EXT_FORWARDING_REQUEST,
  2291.                  NULLOID,
  2292.                  _ZSequenceNumberExt,
  2293.                  &_ZExt_mod,
  2294.                  build_ext_int,
  2295.                  "Extensions.ForwardingRequest.SequenceNumber",
  2296.                  ep) == NOTOK)
  2297.                 return NOTOK;
  2298.             if (*ep)
  2299.                 ep = &(*ep) -> next;
  2300.         }
  2301.         if (qp -> proof_of_submission_request) {
  2302.             if (build_ext_generic
  2303.                 ((caddr_t)&qp -> proof_of_submission_request,
  2304.                  qp -> proof_of_submission_crit,
  2305.                  EXT_PROOF_OF_SUBMISSION_REQUEST_DC,
  2306.                  EXT_PROOF_OF_SUBMISSION_REQUEST,
  2307.                  NULLOID,
  2308.                  _ZProofOfSubmissionRequestExt,
  2309.                  &_ZExt_mod,
  2310.                  build_ext_int,
  2311.                  "Extensions.ProofOfSubmissionRequest",
  2312.                  ep) == NOTOK)
  2313.                 return NOTOK;
  2314.             if (*ep)
  2315.                 ep = &(*ep) -> next;
  2316.         }
  2317.     }
  2318.     return OK;
  2319. }
  2320.  
  2321. static int build_drc_extensions (qp, dr, extp)
  2322. Q_struct *qp;
  2323. DRmpdu *dr;
  2324. struct type_MTA_Extensions **extp;
  2325. {
  2326.     struct type_MTA_Extensions **ep;
  2327.  
  2328.     *extp = NULL;
  2329.  
  2330.     if (build_gen_extensions (dr -> dr_per_report_extensions,
  2331.                   extp) == NOTOK)
  2332.         return NOTOK;
  2333.  
  2334.     for (ep = extp; *ep; ep = &(*ep) -> next)
  2335.         continue;
  2336.  
  2337.     if (qp -> general_content_correlator) {
  2338.         if (build_ext_secure (qp -> general_content_correlator,
  2339.                      qp -> content_correlator_crit,
  2340.                      EXT_CONTENT_CORRELATOR_DC,
  2341.                      EXT_CONTENT_CORRELATOR,
  2342.                      NULLOID,
  2343.                      _ZContentCorrelatorExt,
  2344.                      &_ZExt_mod,
  2345.                      "Extensions.ContentCorrelator",
  2346.                      ep) == NOTOK)
  2347.             return NOTOK;
  2348.         if (*ep &&
  2349.             ps_get_abs ((*ep) -> ExtensionField -> value) >
  2350.             UB_CONTENT_CORRELATOR_LENGTH)
  2351.             return setuberror ("ContentCorrelator",
  2352.                        ps_get_abs ((*ep) -> ExtensionField -> value),
  2353.                        UB_CONTENT_CORRELATOR_LENGTH,
  2354.                        DRD_SIZE_CONSTRAINT_VIOLATION);
  2355.         if (*ep)
  2356.             ep = &(*ep) -> next;
  2357.     }
  2358.     return OK;
  2359. }
  2360.  
  2361.  
  2362. static int build_drc_pr_extensions (qp, rr, extp)
  2363. Q_struct *qp;
  2364. Rrinfo *rr;
  2365. struct type_MTA_Extensions **extp;
  2366. {
  2367.     struct type_MTA_Extensions **ep;
  2368.  
  2369.     *extp = NULL;
  2370.  
  2371.     if (build_gen_extensions (rr -> rr_per_recip_extensions,
  2372.                   extp) == NOTOK)
  2373.         return NOTOK;
  2374.  
  2375.     for (ep = extp; *ep; ep = &(*ep) -> next)
  2376.         continue;
  2377.  
  2378.     if (rr -> rr_redirect_history) {
  2379.         if (build_ext_generic ((caddr_t)rr -> rr_redirect_history,
  2380.                        rr -> rr_redirect_history_crit,
  2381.                        EXT_REDIRECTION_HISTORY_DC,
  2382.                        EXT_REDIRECTION_HISTORY,
  2383.                        NULLOID,
  2384.                        _ZRedirectionHistoryExt,
  2385.                        &_ZExt_mod,
  2386.                        build_aext_redir,
  2387.                        "Extensions.RedirectionHistory",
  2388.                        ep) == NOTOK)
  2389.             return NOTOK;
  2390.         
  2391.         if (*ep)
  2392.             ep = &(*ep) -> next;
  2393.     }
  2394.  
  2395.     if (rr -> rr_physical_fwd_addr) {
  2396.         if (build_ext_generic ((caddr_t) rr -> rr_physical_fwd_addr,
  2397.                        rr -> rr_physical_fwd_addr_crit,
  2398.                        EXT_PHYSICAL_FORWARDING_ADDRESS_DC,
  2399.                        EXT_PHYSICAL_FORWARDING_ADDRESS,
  2400.                        NULLOID,
  2401.                        _ZPhysicalForwardingAddressExt,
  2402.                        &_ZExt_mod,
  2403.                        build_ext_fn,
  2404.                        "Extensions.PhysicalForwardingAddress",
  2405.                        ep) == NOTOK)
  2406.             return NOTOK;
  2407.         if (*ep)
  2408.             ep = &(*ep) -> next;
  2409.     }        
  2410.  
  2411.     if (rr -> rr_recip_certificate) {
  2412.         if (build_ext_secure (rr -> rr_recip_certificate,
  2413.                       rr -> rr_recip_certificate_crit,
  2414.                       EXT_RECIPIENT_CERTIFICATE_DC,
  2415.                       EXT_RECIPIENT_CERTIFICATE,
  2416.                       NULLOID,
  2417.                       _ZRecipientCertificateMTA,
  2418.                       &_ZMTA_mod,
  2419.                       "Extensions.RecipientCertificate",
  2420.                       ep) == NOTOK)
  2421.             return NOTOK;
  2422.         if (*ep)
  2423.             ep = &(*ep) -> next;
  2424.     }
  2425.  
  2426.     if (rr -> rr_report_origin_authentication_check) {
  2427.         if (build_ext_secure (rr -> rr_report_origin_authentication_check,
  2428.                       rr -> rr_report_origin_authentication_check_crit,
  2429.                       EXT_PROOF_OF_DELIVERY_DC,
  2430.                       EXT_PROOF_OF_DELIVERY,
  2431.                       NULLOID,
  2432.                       _ZProofOfDeliveryToks,
  2433.                       &_ZToks_mod,
  2434.                       "Extensions.ProofOfDelivery",
  2435.                       ep) == NOTOK)
  2436.             return NOTOK;
  2437.         if (*ep)
  2438.             ep = &(*ep) -> next;
  2439.     }
  2440.  
  2441.     return OK;
  2442. }
  2443.  
  2444. static int build_prf_ext (ad,p1,msg, extlp)
  2445. ADDR    *ad;
  2446. int    p1,msg; 
  2447. struct type_MTA_Extensions **extlp;
  2448. {
  2449.     struct type_MTA_Extensions **ep;
  2450.  
  2451.     if (build_gen_extensions (ad -> ad_per_recip_ext_list, extlp) == NOTOK)
  2452.         return NOTOK;
  2453.  
  2454.     for (ep = extlp; *ep; ep = &(*ep) -> next)
  2455.         continue;
  2456. #define bump(x)    if (*(x)) (x) = &(*x) -> next
  2457.  
  2458.     if (ad -> ad_orig_req_alt) {
  2459.         if (build_ext_generic
  2460.             (ad -> ad_orig_req_alt,
  2461.              ad -> ad_orig_req_alt_crit,
  2462.              EXT_ORIGINATOR_REQUESTED_ALTERNATE_RECIPIENT_DC,
  2463.              EXT_ORIGINATOR_REQUESTED_ALTERNATE_RECIPIENT,
  2464.              NULLOID,
  2465.              _ZOriginatorRequestedAlternateRecipientExt,
  2466.              &_ZExt_mod,
  2467.              build_aext_oraa,
  2468.              "Extensions.OriginatorRequestedAlternateRecipient",
  2469.              ep) == NOTOK)
  2470.             return NOTOK;
  2471.         bump(ep);
  2472.     }
  2473.     if (ad -> ad_req_del[0] != AD_RDM_NOTUSED) {
  2474.         if (build_ext_generic ((caddr_t)ad -> ad_req_del,
  2475.                        ad -> ad_req_del_crit,
  2476.                        EXT_REQUESTED_DELIVERY_METHOD_DC,
  2477.                        EXT_REQUESTED_DELIVERY_METHOD,
  2478.                        NULLOID,
  2479.                        _ZRequestedDeliveryMethodExt,
  2480.                        &_ZExt_mod,
  2481.                        build_aext_rdm,
  2482.                        "Extensions.RequestedDeliveryMethod",
  2483.                        ep) == NOTOK)
  2484.             return NOTOK;
  2485.         bump(ep);
  2486.     }
  2487.  
  2488.     if (ad -> ad_phys_rendition_attribs) {
  2489.         if (build_ext_generic
  2490.             ((caddr_t)ad -> ad_phys_rendition_attribs,
  2491.              ad -> ad_phys_rendition_attribs_crit,
  2492.              EXT_PHYSICAL_RENDITION_ATTRIBUTES_DC,
  2493.              EXT_PHYSICAL_RENDITION_ATTRIBUTES,
  2494.              NULLOID,
  2495.              _ZPhysicalRenditionAttributesExt,
  2496.              &_ZExt_mod,
  2497.              build_aext_pra,
  2498.              "Extensions.PhysicalRenditionAttributes",
  2499.              ep) == NOTOK)
  2500.             return NOTOK;
  2501.         bump(ep);
  2502.     }
  2503.     if (msg) {
  2504.         if (ad -> ad_phys_forward) {
  2505.             if (build_ext_generic
  2506.                 (&ad -> ad_phys_forward,
  2507.                  ad -> ad_phys_forward_crit,
  2508.                  EXT_PHYSICAL_FORWARDING_PROHIBITED_DC,
  2509.                  EXT_PHYSICAL_FORWARDING_PROHIBITED,
  2510.                  NULLOID,
  2511.                  _ZPhysicalForwardingProhibitedExt,
  2512.                  &_ZExt_mod,
  2513.                  build_ext_char,
  2514.                  "Extensions.PhysicalForwardingProhibited",
  2515.                  ep) == NOTOK)
  2516.                 return NOTOK;
  2517.             bump(ep);
  2518.         }
  2519.         if (ad -> ad_phys_fw_ad_req) {
  2520.             if (build_ext_generic
  2521.                 (&ad -> ad_phys_fw_ad_req,
  2522.                  ad -> ad_phys_fw_ad_crit,
  2523.                  EXT_PHYSICAL_FORWARDING_ADDRESS_REQUEST_DC,
  2524.                  EXT_PHYSICAL_FORWARDING_ADDRESS_REQUEST,
  2525.                  NULLOID,
  2526.                  _ZPhysicalForwardingAddressRequestExt,
  2527.                  &_ZExt_mod,
  2528.                  build_ext_char,
  2529.                  "Extensions.PhysicalForwardingAddressRequest",
  2530.                  ep) == NOTOK)
  2531.                 return NOTOK;
  2532.             bump(ep);
  2533.         }
  2534.         if (ad -> ad_phys_modes) {
  2535.             if (build_ext_generic
  2536.                 ((caddr_t)&ad -> ad_phys_modes,
  2537.                  ad -> ad_phys_modes_crit,
  2538.                  EXT_PHYSICAL_DELIVERY_MODES_DC,
  2539.                  EXT_PHYSICAL_DELIVERY_MODES,
  2540.                  NULLOID,
  2541.                  _ZPhysicalDeliveryModesExt,
  2542.                  &_ZExt_mod,
  2543.                  build_aext_pdm,
  2544.                  "Extensions.PhysicalDeliveryModes",
  2545.                  ep) == NOTOK)
  2546.                 return NOTOK;
  2547.             bump(ep);
  2548.         }
  2549.  
  2550.         if (ad -> ad_reg_mail_type) {
  2551.             if (build_ext_generic
  2552.                 ((caddr_t)&ad -> ad_reg_mail_type,
  2553.                  ad -> ad_reg_mail_type_crit,
  2554.                  EXT_REGISTERED_MAIL_DC,
  2555.                  EXT_REGISTERED_MAIL,
  2556.                  NULLOID,
  2557.                  _ZRegisteredMailTypeExt,
  2558.                  &_ZExt_mod,
  2559.                  build_ext_int,
  2560.                  "Extensions.RegisteredMailType",
  2561.                  ep) == NOTOK)
  2562.                 return NOTOK;
  2563.             bump (ep);
  2564.         }
  2565.         if (ad -> ad_recip_number_for_advice) {
  2566.             if (build_ext_generic
  2567.                 (ad -> ad_recip_number_for_advice,
  2568.                  ad -> ad_recip_number_for_advice_crit,
  2569.                  EXT_RECIPIENT_NUMBER_FOR_ADVICE_DC,
  2570.                  EXT_RECIPIENT_NUMBER_FOR_ADVICE,
  2571.                  NULLOID,
  2572.                  _ZRecipientNumberForAdviceExt,
  2573.                  &_ZExt_mod,
  2574.                  build_aext_rnfa,
  2575.                  "Extensions.RecipientNumberForAdvice",
  2576.                  ep) == NOTOK)
  2577.                 return NOTOK;
  2578.             bump (ep);
  2579.         }
  2580.         if (ad -> ad_pd_report_request) {
  2581.             if (build_ext_generic
  2582.                 ((caddr_t)&ad -> ad_pd_report_request,
  2583.                  ad -> ad_pd_report_request_crit,
  2584.                  EXT_PHYSICAL_DELIVERY_REPORT_REQUEST_DC,
  2585.                  EXT_PHYSICAL_DELIVERY_REPORT_REQUEST,
  2586.                  NULLOID,
  2587.                  _ZPhysicalDeliveryReportRequestExt,
  2588.                  &_ZExt_mod,
  2589.                  build_ext_int,
  2590.                  "Extensions.PhysicalDeliveryReportRequest",
  2591.                  ep) == NOTOK)
  2592.                 return NOTOK;
  2593.             bump (ep);
  2594.         }
  2595.         if (ad -> ad_message_token) {
  2596.             if (build_ext_secure (ad -> ad_message_token,
  2597.                           ad -> ad_message_token_crit,
  2598.                           EXT_MESSAGE_TOKEN_DC,
  2599.                           EXT_MESSAGE_TOKEN,
  2600.                           NULLOID,
  2601.                           _ZMessageTokenExt,
  2602.                           &_ZExt_mod,
  2603.                           "Extensions.MessageToken",
  2604.                           ep) == NOTOK)
  2605.                 return NOTOK;
  2606.             bump (ep);
  2607.         }
  2608.         if (ad -> ad_content_integrity) {
  2609.             if (build_ext_secure (ad -> ad_content_integrity,
  2610.                         ad -> ad_content_integrity_crit,
  2611.                         EXT_CONTENT_INTEGRITY_CHECK_DC,
  2612.                         EXT_CONTENT_INTEGRITY_CHECK,
  2613.                         NULLOID,
  2614.                         _ZContentIntegrityCheckExt,
  2615.                         &_ZExt_mod,
  2616.                         "Extensions.ContentIntegrityCheck",
  2617.                         ep) == NOTOK)
  2618.                 return NOTOK;
  2619.             bump(ep);
  2620.         }
  2621.         if (ad -> ad_proof_delivery) {
  2622.             if (build_ext_generic
  2623.                 ((caddr_t)&ad -> ad_proof_delivery,
  2624.                  ad -> ad_proof_delivery_crit,
  2625.                  EXT_PROOF_OF_DELIVERY_REQUEST_DC,
  2626.                  EXT_PROOF_OF_DELIVERY_REQUEST,
  2627.                  NULLOID,
  2628.                  _ZProofOfDeliveryRequestExt,
  2629.                  &_ZExt_mod,
  2630.                  build_ext_int,
  2631.                  "Extensions.ProofOfDeliveryRequest",
  2632.                  ep) == NOTOK)
  2633.                 return NOTOK;
  2634.             bump(ep);
  2635.         }
  2636.     }
  2637.     if (p1) {
  2638.         if (ad -> ad_redirection_history) {
  2639.             if (build_ext_generic
  2640.                 ((caddr_t)ad -> ad_redirection_history,
  2641.                  ad -> ad_redirection_history_crit,
  2642.                  EXT_REDIRECTION_HISTORY_DC,
  2643.                  EXT_REDIRECTION_HISTORY,
  2644.                  NULLOID,
  2645.                  _ZRedirectionHistoryExt,
  2646.                  &_ZExt_mod,
  2647.                  build_aext_redir,
  2648.                  "Extensions.RedirectionHistory",
  2649.                  ep) == NOTOK)
  2650.                 return NOTOK;
  2651.             bump (ep);
  2652.         }
  2653.     }
  2654.     return OK;
  2655. }
  2656.  
  2657. static int build_dre_extensions (dr, extp)
  2658. DRmpdu *dr;
  2659. struct type_MTA_Extensions **extp;
  2660. {
  2661.     struct type_MTA_Extensions **ep;
  2662.  
  2663.     if (build_gen_extensions (dr -> dr_per_envelope_extensions,
  2664.                   extp) == NOTOK)
  2665.         return NOTOK;
  2666.  
  2667.     for (ep = extp; *ep; ep = &(*ep) -> next)
  2668.         continue;
  2669.  
  2670.     if (dr -> dr_trace) {
  2671.         if (build_ext_iti (dr -> dr_trace,
  2672.                    EXT_INTERNAL_TRACE_INFORMATION_DC, ep) == NOTOK)
  2673.             return NOTOK;
  2674.         if (*ep) ep = &(*ep) -> next;
  2675.     }
  2676.     if (dr -> dr_security_label) {
  2677.         if (build_ext_secure (dr -> dr_security_label,
  2678.                       dr -> dr_security_label_crit,
  2679.                       EXT_MESSAGE_SECURITY_LABEL_DC,
  2680.                       EXT_MESSAGE_SECURITY_LABEL,
  2681.                       NULLOID,
  2682.                       _ZMessageSecurityLabelExt,
  2683.                       &_ZExt_mod,
  2684.                       "Extensions.MessageSecurityLabel",
  2685.                       ep) == NOTOK)
  2686.             return NOTOK;
  2687.         if (*ep) ep = &(*ep) -> next;
  2688.     }
  2689.     if (dr -> dr_report_origin_auth_check) {
  2690.         if (build_ext_secure
  2691.             (dr -> dr_report_origin_auth_check,
  2692.              dr -> dr_report_origin_auth_check_crit,
  2693.              EXT_REPORT_ORIGIN_AUTHENTICATION_CHECK_DC,
  2694.              EXT_REPORT_ORIGIN_AUTHENTICATION_CHECK,
  2695.              NULLOID,
  2696.              _ZReportOriginAuthenticationCheckExt,
  2697.              &_ZExt_mod,
  2698.              "Extensions.MessageOriginAuthenticationCheck",
  2699.              ep) == NOTOK)
  2700.                 return NOTOK;
  2701.         if (*ep) ep = &(*ep) -> next;
  2702.     }
  2703.     if (dr -> dr_reporting_mta_certificate) {
  2704.         if (build_ext_secure
  2705.             (dr -> dr_reporting_mta_certificate,
  2706.              dr -> dr_reporting_mta_certificate_crit,
  2707.              EXT_REPORTING_MTA_CERTIFICATE_DC,
  2708.              EXT_REPORTING_MTA_CERTIFICATE,
  2709.              NULLOID,
  2710.              _ZReportingMTACertificateExt,
  2711.              &_ZExt_mod,
  2712.              "Extensions.ReportingMTACertificate",
  2713.              ep) == NOTOK)
  2714.             return NOTOK;
  2715.         if (*ep) ep = &(*ep) -> next;
  2716.     }
  2717.     if (dr -> dr_reporting_dl_name) {
  2718.         if (build_ext_generic ((caddr_t)dr -> dr_reporting_dl_name,
  2719.                        dr -> dr_reporting_dl_name_crit,
  2720.                        EXT_REPORT_DL_NAME_DC,
  2721.                        EXT_REPORT_DL_NAME,
  2722.                        NULLOID,
  2723.                        _ZReportingDLNameExt,
  2724.                        &_ZExt_mod,
  2725.                        build_ext_fn,
  2726.                        "Extension.ReportingDLName",
  2727.                        ep) == NOTOK)
  2728.             return NOTOK;
  2729.         if (*ep) ep = &(*ep) -> next;
  2730.     }
  2731.     if (dr -> dr_dl_history) {
  2732.         if (build_ext_generic
  2733.             ((caddr_t)dr -> dr_dl_history,
  2734.              dr -> dr_dl_history_crit,
  2735.              EXT_ORIGINATOR_AND_DL_EXPANSION_HISTORY_DC,
  2736.              EXT_ORIGINATOR_AND_DL_EXPANSION_HISTORY,
  2737.              NULLOID,
  2738.              _ZOriginatorAndDLExpansionHistoryExt,
  2739.              &_ZExt_mod,
  2740.              build_ext_dlh,
  2741.              "Extensions.OriginatorAndDLExpansionHistory",
  2742.              ep) == NOTOK)
  2743.             return NOTOK;
  2744.         if (*ep) ep = &(*ep) -> next;
  2745.     }
  2746.     return OK;
  2747. }
  2748.  
  2749. static int setuberror(msg, length, constrnt, error_code)
  2750. char *msg;
  2751. int length;
  2752. int constrnt;
  2753. {
  2754.     (void) sprintf (ub_error_string,
  2755.             "Upper bound constraint exceeded: %s (%d > %d)",
  2756.             msg, length, constrnt);
  2757.     PP_LOG(LLOG_EXCEPTIONS, ("%s", ub_error_string));
  2758.     ub_error_set = error_code;
  2759.     return NOTOK;
  2760. }
  2761.